use of org.h2.command.dml.Insert in project h2database by h2database.
the class ScriptCommand method add.
private void add(String s, boolean insert) throws IOException {
if (s == null) {
return;
}
if (lineSeparator.length > 1 || lineSeparator[0] != '\n') {
s = StringUtils.replaceAll(s, "\n", lineSeparatorString);
}
s += ";";
if (out != null) {
byte[] buff = s.getBytes(charset);
int len = MathUtils.roundUpInt(buff.length + lineSeparator.length, Constants.FILE_BLOCK_SIZE);
buffer = Utils.copy(buff, buffer);
if (len > buffer.length) {
buffer = new byte[len];
}
System.arraycopy(buff, 0, buffer, 0, buff.length);
for (int i = buff.length; i < len - lineSeparator.length; i++) {
buffer[i] = ' ';
}
for (int j = 0, i = len - lineSeparator.length; i < len; i++, j++) {
buffer[i] = lineSeparator[j];
}
out.write(buffer, 0, len);
if (!insert) {
Value[] row = { ValueString.get(s) };
result.addRow(row);
}
} else {
Value[] row = { ValueString.get(s) };
result.addRow(row);
}
}
use of org.h2.command.dml.Insert in project h2database by h2database.
the class ScriptCommand method writeLobStream.
private int writeLobStream(Value v) throws IOException {
if (!tempLobTableCreated) {
add("CREATE TABLE IF NOT EXISTS SYSTEM_LOB_STREAM" + "(ID INT NOT NULL, PART INT NOT NULL, " + "CDATA VARCHAR, BDATA BINARY)", true);
add("CREATE PRIMARY KEY SYSTEM_LOB_STREAM_PRIMARY_KEY " + "ON SYSTEM_LOB_STREAM(ID, PART)", true);
add("CREATE ALIAS IF NOT EXISTS " + "SYSTEM_COMBINE_CLOB FOR \"" + this.getClass().getName() + ".combineClob\"", true);
add("CREATE ALIAS IF NOT EXISTS " + "SYSTEM_COMBINE_BLOB FOR \"" + this.getClass().getName() + ".combineBlob\"", true);
tempLobTableCreated = true;
}
int id = nextLobId++;
switch(v.getType()) {
case Value.BLOB:
{
byte[] bytes = new byte[lobBlockSize];
try (InputStream input = v.getInputStream()) {
for (int i = 0; ; i++) {
StringBuilder buff = new StringBuilder(lobBlockSize * 2);
buff.append("INSERT INTO SYSTEM_LOB_STREAM VALUES(").append(id).append(", ").append(i).append(", NULL, '");
int len = IOUtils.readFully(input, bytes, lobBlockSize);
if (len <= 0) {
break;
}
buff.append(StringUtils.convertBytesToHex(bytes, len)).append("')");
String sql = buff.toString();
add(sql, true);
}
}
break;
}
case Value.CLOB:
{
char[] chars = new char[lobBlockSize];
try (Reader reader = v.getReader()) {
for (int i = 0; ; i++) {
StringBuilder buff = new StringBuilder(lobBlockSize * 2);
buff.append("INSERT INTO SYSTEM_LOB_STREAM VALUES(").append(id).append(", ").append(i).append(", ");
int len = IOUtils.readFully(reader, chars, lobBlockSize);
if (len == 0) {
break;
}
buff.append(StringUtils.quoteStringSQL(new String(chars, 0, len))).append(", NULL)");
String sql = buff.toString();
add(sql, true);
}
}
break;
}
default:
DbException.throwInternalError("type:" + v.getType());
}
return id;
}
use of org.h2.command.dml.Insert in project h2database by h2database.
the class Merge method merge.
/**
* Merge the given row.
*
* @param row the row
*/
protected void merge(Row row) {
ArrayList<Parameter> k = update.getParameters();
for (int i = 0; i < columns.length; i++) {
Column col = columns[i];
Value v = row.getValue(col.getColumnId());
Parameter p = k.get(i);
p.setValue(v);
}
for (int i = 0; i < keys.length; i++) {
Column col = keys[i];
Value v = row.getValue(col.getColumnId());
if (v == null) {
throw DbException.get(ErrorCode.COLUMN_CONTAINS_NULL_VALUES_1, col.getSQL());
}
Parameter p = k.get(columns.length + i);
p.setValue(v);
}
// try and update
int count = update.update();
// if update fails try an insert
if (count == 0) {
try {
targetTable.validateConvertUpdateSequence(session, row);
boolean done = targetTable.fireBeforeRow(session, null, row);
if (!done) {
targetTable.lock(session, true, false);
targetTable.addRow(session, row);
session.getGeneratedKeys().confirmRow(row);
session.log(targetTable, UndoLogRecord.INSERT, row);
targetTable.fireAfterRow(session, null, row, false);
}
} catch (DbException e) {
if (e.getErrorCode() == ErrorCode.DUPLICATE_KEY_1) {
// possibly a concurrent merge or insert
Index index = (Index) e.getSource();
if (index != null) {
// verify the index columns match the key
Column[] indexColumns = index.getColumns();
boolean indexMatchesKeys = true;
if (indexColumns.length <= keys.length) {
for (int i = 0; i < indexColumns.length; i++) {
if (indexColumns[i] != keys[i]) {
indexMatchesKeys = false;
break;
}
}
}
if (indexMatchesKeys) {
throw DbException.get(ErrorCode.CONCURRENT_UPDATE_1, targetTable.getName());
}
}
}
throw e;
}
} else if (count != 1) {
throw DbException.get(ErrorCode.DUPLICATE_KEY_1, targetTable.getSQL());
}
}
use of org.h2.command.dml.Insert in project h2database by h2database.
the class CreateTable method update.
@Override
public int update() {
if (!transactional) {
session.commit(true);
}
Database db = session.getDatabase();
if (!db.isPersistent()) {
data.persistIndexes = false;
}
boolean isSessionTemporary = data.temporary && !data.globalTemporary;
if (!isSessionTemporary) {
db.lockMeta(session);
}
if (getSchema().resolveTableOrView(session, data.tableName) != null) {
if (ifNotExists) {
return 0;
}
throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, data.tableName);
}
if (asQuery != null) {
asQuery.prepare();
if (data.columns.isEmpty()) {
generateColumnsFromQuery();
} else if (data.columns.size() != asQuery.getColumnCount()) {
throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
}
}
changePrimaryKeysToNotNull(data.columns);
data.id = getObjectId();
data.create = create;
data.session = session;
Table table = getSchema().createTable(data);
ArrayList<Sequence> sequences = generateSequences(data.columns, data.temporary);
table.setComment(comment);
if (isSessionTemporary) {
if (onCommitDrop) {
table.setOnCommitDrop(true);
}
if (onCommitTruncate) {
table.setOnCommitTruncate(true);
}
session.addLocalTempTable(table);
} else {
db.lockMeta(session);
db.addSchemaObject(session, table);
}
try {
for (Column c : data.columns) {
c.prepareExpression(session);
}
for (Sequence sequence : sequences) {
table.addSequence(sequence);
}
createConstraints();
if (asQuery != null) {
boolean old = session.isUndoLogEnabled();
try {
session.setUndoLogEnabled(false);
session.startStatementWithinTransaction();
Insert insert = new Insert(session);
insert.setSortedInsertMode(sortedInsertMode);
insert.setQuery(asQuery);
insert.setTable(table);
insert.setInsertFromSelect(true);
insert.prepare();
insert.update();
} finally {
session.setUndoLogEnabled(old);
}
}
HashSet<DbObject> set = new HashSet<>();
set.clear();
table.addDependencies(set);
for (DbObject obj : set) {
if (obj == table) {
continue;
}
if (obj.getType() == DbObject.TABLE_OR_VIEW) {
if (obj instanceof Table) {
Table t = (Table) obj;
if (t.getId() > table.getId()) {
throw DbException.get(ErrorCode.FEATURE_NOT_SUPPORTED_1, "Table depends on another table " + "with a higher ID: " + t + ", this is currently not supported, " + "as it would prevent the database from " + "being re-opened");
}
}
}
}
} catch (DbException e) {
db.checkPowerOff();
db.removeSchemaObject(session, table);
if (!transactional) {
session.commit(true);
}
throw e;
}
return 0;
}
use of org.h2.command.dml.Insert in project h2database by h2database.
the class ConstraintReferential method checkRowRefTable.
private void checkRowRefTable(Session session, Row oldRow, Row newRow) {
if (oldRow == null) {
// this is an insert
return;
}
if (newRow != null && isEqual(oldRow, newRow)) {
// on an update, if both old and new are the same, don't do anything
return;
}
if (newRow == null) {
// this is a delete
if (deleteAction == ConstraintActionType.RESTRICT) {
checkRow(session, oldRow);
} else {
int i = deleteAction == ConstraintActionType.CASCADE ? 0 : columns.length;
Prepared deleteCommand = getDelete(session);
setWhere(deleteCommand, i, oldRow);
updateWithSkipCheck(deleteCommand);
}
} else {
// this is an update
if (updateAction == ConstraintActionType.RESTRICT) {
checkRow(session, oldRow);
} else {
Prepared updateCommand = getUpdate(session);
if (updateAction == ConstraintActionType.CASCADE) {
ArrayList<Parameter> params = updateCommand.getParameters();
for (int i = 0, len = columns.length; i < len; i++) {
Parameter param = params.get(i);
Column refCol = refColumns[i].column;
param.setValue(newRow.getValue(refCol.getColumnId()));
}
}
setWhere(updateCommand, columns.length, oldRow);
updateWithSkipCheck(updateCommand);
}
}
}
Aggregations