use of org.h2.engine.User in project ignite by apache.
the class H2TableDescriptor method createUserIndex.
/**
* Create user index.
*
* @param idxDesc Index descriptor.
* @return Index.
*/
public GridH2IndexBase createUserIndex(GridQueryIndexDescriptor idxDesc) {
IndexColumn keyCol = tbl.indexColumn(KEY_COL, SortOrder.ASCENDING);
IndexColumn affCol = tbl.getAffinityKeyColumn();
List<IndexColumn> cols = new ArrayList<>(idxDesc.fields().size() + 2);
for (String field : idxDesc.fields()) {
Column col = tbl.getColumn(field);
cols.add(tbl.indexColumn(col.getColumnId(), idxDesc.descending(field) ? SortOrder.DESCENDING : SortOrder.ASCENDING));
}
GridH2RowDescriptor desc = tbl.rowDescriptor();
if (idxDesc.type() == QueryIndexType.SORTED) {
cols = H2Utils.treeIndexColumns(desc, cols, keyCol, affCol);
return idx.createSortedIndex(idxDesc.name(), tbl, false, cols, idxDesc.inlineSize());
} else if (idxDesc.type() == QueryIndexType.GEOSPATIAL)
return H2Utils.createSpatialIndex(tbl, idxDesc.name(), cols.toArray(new IndexColumn[cols.size()]));
throw new IllegalStateException("Index type: " + idxDesc.type());
}
use of org.h2.engine.User in project ignite by apache.
the class DmlUtils method convert.
/**
* Convert value to column's expected type by means of H2.
*
* @param val Source value.
* @param desc Row descriptor.
* @param expCls Expected value class.
* @param type Expected column type to convert to.
* @return Converted object.
* @throws IgniteCheckedException if failed.
*/
@SuppressWarnings({ "ConstantConditions", "SuspiciousSystemArraycopy" })
public static Object convert(Object val, GridH2RowDescriptor desc, Class<?> expCls, int type) throws IgniteCheckedException {
if (val == null)
return null;
Class<?> currCls = val.getClass();
try {
if (val instanceof Date && currCls != Date.class && expCls == Date.class) {
// precise Date instance. Let's satisfy it.
return new Date(((Date) val).getTime());
}
// User-given UUID is always serialized by H2 to byte array, so we have to deserialize manually
if (type == Value.UUID && currCls == byte[].class)
return U.unmarshal(desc.context().marshaller(), (byte[]) val, U.resolveClassLoader(desc.context().gridConfig()));
if (LocalDateTimeUtils.isJava8DateApiPresent()) {
if (val instanceof Timestamp && LocalDateTimeUtils.isLocalDateTime(expCls))
return LocalDateTimeUtils.valueToLocalDateTime(ValueTimestamp.get((Timestamp) val));
if (val instanceof Date && LocalDateTimeUtils.isLocalDate(expCls))
return LocalDateTimeUtils.valueToLocalDate(ValueDate.fromDateValue(DateTimeUtils.dateValueFromDate(((Date) val).getTime())));
if (val instanceof Time && LocalDateTimeUtils.isLocalTime(expCls))
return LocalDateTimeUtils.valueToLocalTime(ValueTime.get((Time) val));
}
// Still, we only can convert from Object[] to something more precise.
if (type == Value.ARRAY && currCls != expCls) {
if (currCls != Object[].class)
throw new IgniteCheckedException("Unexpected array type - only conversion from Object[] " + "is assumed");
// Why would otherwise type be Value.ARRAY?
assert expCls.isArray();
Object[] curr = (Object[]) val;
Object newArr = Array.newInstance(expCls.getComponentType(), curr.length);
System.arraycopy(curr, 0, newArr, 0, curr.length);
return newArr;
}
Object res = H2Utils.convert(val, desc, type);
if (res instanceof Date && res.getClass() != Date.class && expCls == Date.class) {
// without query - let's handle this
return new Date(((Date) res).getTime());
}
return res;
} catch (Exception e) {
throw new IgniteSQLException("Value conversion failed [from=" + currCls.getName() + ", to=" + expCls.getName() + ']', IgniteQueryErrorCode.CONVERSION_FAILED, e);
}
}
use of org.h2.engine.User in project ignite by apache.
the class UpdatePlanBuilder method planForUpdate.
/**
* Prepare update plan for UPDATE or DELETE.
*
* @param stmt UPDATE or DELETE statement.
* @param loc Local query flag.
* @param idx Indexing.
* @param conn Connection.
* @param fieldsQuery Original query.
* @param errKeysPos index to inject param for re-run keys at. Null if it's not a re-run plan.
* @return Update plan.
* @throws IgniteCheckedException if failed.
*/
private static UpdatePlan planForUpdate(GridSqlStatement stmt, boolean loc, IgniteH2Indexing idx, @Nullable Connection conn, @Nullable SqlFieldsQuery fieldsQuery, @Nullable Integer errKeysPos) throws IgniteCheckedException {
GridSqlElement target;
FastUpdate fastUpdate;
UpdateMode mode;
if (stmt instanceof GridSqlUpdate) {
// Let's verify that user is not trying to mess with key's columns directly
verifyUpdateColumns(stmt);
GridSqlUpdate update = (GridSqlUpdate) stmt;
target = update.target();
fastUpdate = DmlAstUtils.getFastUpdateArgs(update);
mode = UpdateMode.UPDATE;
} else if (stmt instanceof GridSqlDelete) {
GridSqlDelete del = (GridSqlDelete) stmt;
target = del.from();
fastUpdate = DmlAstUtils.getFastDeleteArgs(del);
mode = UpdateMode.DELETE;
} else
throw new IgniteSQLException("Unexpected DML operation [cls=" + stmt.getClass().getName() + ']', IgniteQueryErrorCode.UNEXPECTED_OPERATION);
GridSqlTable tbl = DmlAstUtils.gridTableForElement(target);
GridH2Table h2Tbl = tbl.dataTable();
GridH2RowDescriptor desc = h2Tbl.rowDescriptor();
if (desc == null)
throw new IgniteSQLException("Row descriptor undefined for table '" + h2Tbl.getName() + "'", IgniteQueryErrorCode.NULL_TABLE_DESCRIPTOR);
if (fastUpdate != null) {
return new UpdatePlan(mode, h2Tbl, null, fastUpdate, null);
} else {
GridSqlSelect sel;
if (stmt instanceof GridSqlUpdate) {
List<GridSqlColumn> updatedCols = ((GridSqlUpdate) stmt).cols();
int valColIdx = -1;
String[] colNames = new String[updatedCols.size()];
int[] colTypes = new int[updatedCols.size()];
for (int i = 0; i < updatedCols.size(); i++) {
colNames[i] = updatedCols.get(i).columnName();
colTypes[i] = updatedCols.get(i).resultType().type();
Column col = updatedCols.get(i).column();
if (desc.isValueColumn(col.getColumnId()))
valColIdx = i;
}
boolean hasNewVal = (valColIdx != -1);
// Statement updates distinct properties if it does not have _val in updated columns list
// or if its list of updated columns includes only _val, i.e. is single element.
boolean hasProps = !hasNewVal || updatedCols.size() > 1;
// Index of new _val in results of SELECT
if (hasNewVal)
valColIdx += 2;
int newValColIdx = (hasNewVal ? valColIdx : 1);
KeyValueSupplier valSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps, false, true);
sel = DmlAstUtils.selectForUpdate((GridSqlUpdate) stmt, errKeysPos);
String selectSql = sel.getSQL();
DmlDistributedPlanInfo distributed = F.isEmpty(selectSql) ? null : checkPlanCanBeDistributed(idx, conn, fieldsQuery, loc, selectSql, tbl.dataTable().cacheName());
return new UpdatePlan(UpdateMode.UPDATE, h2Tbl, colNames, colTypes, null, valSupplier, -1, valColIdx, selectSql, false, null, 0, null, distributed);
} else {
sel = DmlAstUtils.selectForDelete((GridSqlDelete) stmt, errKeysPos);
String selectSql = sel.getSQL();
DmlDistributedPlanInfo distributed = F.isEmpty(selectSql) ? null : checkPlanCanBeDistributed(idx, conn, fieldsQuery, loc, selectSql, tbl.dataTable().cacheName());
return new UpdatePlan(UpdateMode.DELETE, h2Tbl, selectSql, null, distributed);
}
}
}
use of org.h2.engine.User in project h2database by h2database.
the class Database method open.
private synchronized void open(int traceLevelFile, int traceLevelSystemOut) {
if (persistent) {
String dataFileName = databaseName + Constants.SUFFIX_OLD_DATABASE_FILE;
boolean existsData = FileUtils.exists(dataFileName);
String pageFileName = databaseName + Constants.SUFFIX_PAGE_FILE;
String mvFileName = databaseName + Constants.SUFFIX_MV_FILE;
boolean existsPage = FileUtils.exists(pageFileName);
boolean existsMv = FileUtils.exists(mvFileName);
if (existsData && (!existsPage && !existsMv)) {
throw DbException.get(ErrorCode.FILE_VERSION_ERROR_1, "Old database: " + dataFileName + " - please convert the database " + "to a SQL script and re-create it.");
}
if (existsPage && !FileUtils.canWrite(pageFileName)) {
readOnly = true;
}
if (existsMv && !FileUtils.canWrite(mvFileName)) {
readOnly = true;
}
if (existsPage && !existsMv) {
dbSettings.mvStore = false;
}
if (readOnly) {
if (traceLevelFile >= TraceSystem.DEBUG) {
String traceFile = Utils.getProperty("java.io.tmpdir", ".") + "/" + "h2_" + System.currentTimeMillis();
traceSystem = new TraceSystem(traceFile + Constants.SUFFIX_TRACE_FILE);
} else {
traceSystem = new TraceSystem(null);
}
} else {
traceSystem = new TraceSystem(databaseName + Constants.SUFFIX_TRACE_FILE);
}
traceSystem.setLevelFile(traceLevelFile);
traceSystem.setLevelSystemOut(traceLevelSystemOut);
trace = traceSystem.getTrace(Trace.DATABASE);
trace.info("opening {0} (build {1})", databaseName, Constants.BUILD_ID);
if (autoServerMode) {
if (readOnly || fileLockMethod == FileLockMethod.NO || fileLockMethod == FileLockMethod.SERIALIZED || fileLockMethod == FileLockMethod.FS || !persistent) {
throw DbException.getUnsupportedException("autoServerMode && (readOnly || " + "fileLockMethod == NO || " + "fileLockMethod == SERIALIZED || " + "fileLockMethod == FS || " + "inMemory)");
}
}
String lockFileName = databaseName + Constants.SUFFIX_LOCK_FILE;
if (readOnly) {
if (FileUtils.exists(lockFileName)) {
throw DbException.get(ErrorCode.DATABASE_ALREADY_OPEN_1, "Lock file exists: " + lockFileName);
}
}
if (!readOnly && fileLockMethod != FileLockMethod.NO) {
if (fileLockMethod != FileLockMethod.FS) {
lock = new FileLock(traceSystem, lockFileName, Constants.LOCK_SLEEP);
lock.lock(fileLockMethod);
if (autoServerMode) {
startServer(lock.getUniqueId());
}
}
}
if (SysProperties.MODIFY_ON_WRITE) {
while (isReconnectNeeded()) {
// wait until others stopped writing
}
} else {
while (isReconnectNeeded() && !beforeWriting()) {
// wait until others stopped writing and
// until we can write (the file is not yet open -
// no need to re-connect)
}
}
deleteOldTempFiles();
starting = true;
if (SysProperties.MODIFY_ON_WRITE) {
try {
getPageStore();
} catch (DbException e) {
if (e.getErrorCode() != ErrorCode.DATABASE_IS_READ_ONLY) {
throw e;
}
pageStore = null;
while (!beforeWriting()) {
// wait until others stopped writing and
// until we can write (the file is not yet open -
// no need to re-connect)
}
getPageStore();
}
} else {
getPageStore();
}
starting = false;
if (mvStore == null) {
writer = WriterThread.create(this, writeDelay);
} else {
setWriteDelay(writeDelay);
}
} else {
if (autoServerMode) {
throw DbException.getUnsupportedException("autoServerMode && inMemory");
}
traceSystem = new TraceSystem(null);
trace = traceSystem.getTrace(Trace.DATABASE);
if (dbSettings.mvStore) {
getPageStore();
}
}
systemUser = new User(this, 0, SYSTEM_USER_NAME, true);
mainSchema = new Schema(this, 0, Constants.SCHEMA_MAIN, systemUser, true);
infoSchema = new Schema(this, -1, "INFORMATION_SCHEMA", systemUser, true);
schemas.put(mainSchema.getName(), mainSchema);
schemas.put(infoSchema.getName(), infoSchema);
publicRole = new Role(this, 0, Constants.PUBLIC_ROLE_NAME, true);
roles.put(Constants.PUBLIC_ROLE_NAME, publicRole);
systemUser.setAdmin(true);
systemSession = new Session(this, systemUser, ++nextSessionId);
lobSession = new Session(this, systemUser, ++nextSessionId);
CreateTableData data = new CreateTableData();
ArrayList<Column> cols = data.columns;
Column columnId = new Column("ID", Value.INT);
columnId.setNullable(false);
cols.add(columnId);
cols.add(new Column("HEAD", Value.INT));
cols.add(new Column("TYPE", Value.INT));
cols.add(new Column("SQL", Value.STRING));
boolean create = true;
if (pageStore != null) {
create = pageStore.isNew();
}
data.tableName = "SYS";
data.id = 0;
data.temporary = false;
data.persistData = persistent;
data.persistIndexes = persistent;
data.create = create;
data.isHidden = true;
data.session = systemSession;
meta = mainSchema.createTable(data);
IndexColumn[] pkCols = IndexColumn.wrap(new Column[] { columnId });
metaIdIndex = meta.addIndex(systemSession, "SYS_ID", 0, pkCols, IndexType.createPrimaryKey(false, false), true, null);
objectIds.set(0);
starting = true;
Cursor cursor = metaIdIndex.find(systemSession, null, null);
ArrayList<MetaRecord> records = New.arrayList();
while (cursor.next()) {
MetaRecord rec = new MetaRecord(cursor.get());
objectIds.set(rec.getId());
records.add(rec);
}
Collections.sort(records);
synchronized (systemSession) {
for (MetaRecord rec : records) {
rec.execute(this, systemSession, eventListener);
}
}
if (mvStore != null) {
mvStore.initTransactions();
mvStore.removeTemporaryMaps(objectIds);
}
recompileInvalidViews(systemSession);
starting = false;
if (!readOnly) {
// set CREATE_BUILD in a new database
String name = SetTypes.getTypeName(SetTypes.CREATE_BUILD);
if (settings.get(name) == null) {
Setting setting = new Setting(this, allocateObjectId(), name);
setting.setIntValue(Constants.BUILD_ID);
lockMeta(systemSession);
addDatabaseObject(systemSession, setting);
}
// mark all ids used in the page store
if (pageStore != null) {
BitSet f = pageStore.getObjectIds();
for (int i = 0, len = f.length(); i < len; i++) {
if (f.get(i) && !objectIds.get(i)) {
trace.info("unused object id: " + i);
objectIds.set(i);
}
}
}
}
getLobStorage().init();
systemSession.commit(true);
trace.info("opened {0}", databaseName);
if (checkpointAllowed > 0) {
afterWriting();
}
}
use of org.h2.engine.User in project h2database by h2database.
the class Engine method openSession.
private Session openSession(ConnectionInfo ci, boolean ifExists, String cipher) {
String name = ci.getName();
Database database;
ci.removeProperty("NO_UPGRADE", false);
boolean openNew = ci.getProperty("OPEN_NEW", false);
boolean opened = false;
User user = null;
synchronized (DATABASES) {
if (openNew || ci.isUnnamedInMemory()) {
database = null;
} else {
database = DATABASES.get(name);
}
if (database == null) {
if (ifExists && !Database.exists(name)) {
throw DbException.get(ErrorCode.DATABASE_NOT_FOUND_1, name);
}
database = new Database(ci, cipher);
opened = true;
if (database.getAllUsers().isEmpty()) {
// users is the last thing we add, so if no user is around,
// the database is new (or not initialized correctly)
user = new User(database, database.allocateObjectId(), ci.getUserName(), false);
user.setAdmin(true);
user.setUserPasswordHash(ci.getUserPasswordHash());
database.setMasterUser(user);
}
if (!ci.isUnnamedInMemory()) {
DATABASES.put(name, database);
}
}
}
if (opened) {
// start the thread when already synchronizing on the database
// otherwise a deadlock can occur when the writer thread
// opens a new database (as in recovery testing)
database.opened();
}
if (database.isClosing()) {
return null;
}
if (user == null) {
if (database.validateFilePasswordHash(cipher, ci.getFilePasswordHash())) {
user = database.findUser(ci.getUserName());
if (user != null) {
if (!user.validateUserPasswordHash(ci.getUserPasswordHash())) {
user = null;
}
}
}
if (opened && (user == null || !user.isAdmin())) {
// reset - because the user is not an admin, and has no
// right to listen to exceptions
database.setEventListener(null);
}
}
if (user == null) {
DbException er = DbException.get(ErrorCode.WRONG_USER_OR_PASSWORD);
database.getTrace(Trace.DATABASE).error(er, "wrong user or password; user: \"" + ci.getUserName() + "\"");
database.removeSession(null);
throw er;
}
checkClustering(ci, database);
Session session = database.createSession(user);
if (session == null) {
// concurrently closing
return null;
}
if (ci.getProperty("JMX", false)) {
try {
Utils.callStaticMethod("org.h2.jmx.DatabaseInfo.registerMBean", ci, database);
} catch (Exception e) {
database.removeSession(session);
throw DbException.get(ErrorCode.FEATURE_NOT_SUPPORTED_1, e, "JMX");
}
jmx = true;
}
return session;
}
Aggregations