private void testFormat() throws IOException { Map<Long, byte[]> map = New.hashMap(); StreamStore store = new StreamStore(map); store.setMinBlockSize(10); store.setMaxBlockSize(20); store.setNextKey(123); byte[] id; id = store.put(new ByteArrayInputStream(new byte[200])); assertEquals(200, store.length(id)); assertEquals("02c8018801", StringUtils.convertBytesToHex(id)); id = store.put(new ByteArrayInputStream(new byte[0])); assertEquals("", StringUtils.convertBytesToHex(id)); id = store.put(new ByteArrayInputStream(new byte[1])); assertEquals("000100", StringUtils.convertBytesToHex(id)); id = store.put(new ByteArrayInputStream(new byte[3])); assertEquals("0003000000", StringUtils.convertBytesToHex(id)); id = store.put(new ByteArrayInputStream(new byte[10])); assertEquals("010a8901", StringUtils.convertBytesToHex(id)); byte[] combined = StringUtils.convertHexToBytes("0001aa0002bbcc"); assertEquals(3, store.length(combined)); InputStream in = store.get(combined); assertEquals(1, in.skip(1)); assertEquals(0xbb, in.read()); assertEquals(1, in.skip(1)); }
private void copyData() { if (table.isTemporary()) { throw DbException.getUnsupportedException("TEMP TABLE"); } Database db = session.getDatabase(); String baseName = table.getName(); String tempName = db.getTempTableName(baseName, session); Column[] columns = table.getColumns(); ArrayList<Column> newColumns = New.arrayList(); Table newTable = cloneTableStructure(columns, db, tempName, newColumns); try { // check if a view would become invalid // (because the column to drop is referenced or so) checkViews(table, newTable); } catch (DbException e) { execute("DROP TABLE " + newTable.getName(), true); throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, e, getSQL(), e.getMessage()); } String tableName = table.getName(); ArrayList<TableView> views = table.getViews(); if (views != null) { views = New.arrayList(views); for (TableView view : views) { table.removeView(view); } } execute("DROP TABLE " + table.getSQL() + " IGNORE", true); db.renameSchemaObject(session, newTable, tableName); for (DbObject child : newTable.getChildren()) { if (child instanceof Sequence) { continue; } String name = child.getName(); if (name == null || child.getCreateSQL() == null) { continue; } if (name.startsWith(tempName + "_")) { name = name.substring(tempName.length() + 1); SchemaObject so = (SchemaObject) child; if (so instanceof Constraint) { if (so.getSchema().findConstraint(session, name) != null) { name = so.getSchema().getUniqueConstraintName(session, newTable); } } else if (so instanceof Index) { if (so.getSchema().findIndex(session, name) != null) { name = so.getSchema().getUniqueIndexName(session, newTable, name); } } db.renameSchemaObject(session, so, name); } } if (views != null) { for (TableView view : views) { String sql = view.getCreateSQL(true, true); execute(sql, true); } } }
@Override public void reset() { if (sort != null) { for (ResultDiskTape tape : tapes) { tape.pos = tape.start; tape.buffer = New.arrayList(); } } else { mainTape.pos = FileStore.HEADER_LENGTH; mainTape.buffer = New.arrayList(); } }
private void initColumnsAndTables(Session session) { Column[] cols; removeViewFromTables(); try { Query query = recompileQuery(session); tables = New.arrayList(query.getTables()); ArrayList<Expression> expressions = query.getExpressions(); ArrayList<Column> list = New.arrayList(); for (int i = 0; i < query.getColumnCount(); i++) { Expression expr = expressions.get(i); String name = null; if (columnNames != null && columnNames.length > i) { name = columnNames[i]; } if (name == null) { name = expr.getAlias(); } int type = expr.getType(); long precision = expr.getPrecision(); int scale = expr.getScale(); int displaySize = expr.getDisplaySize(); Column col = new Column(name, type, precision, scale, displaySize); col.setTable(this, i); list.add(col); } cols = new Column[list.size()]; list.toArray(cols); createException = null; viewQuery = query; } catch (DbException e) { createException = e; // if it can't be compiled, then it's a 'zero column table' // this avoids problems when creating the view when opening the // database tables = New.arrayList(); cols = new Column[0]; if (recursive && columnNames != null) { cols = new Column[columnNames.length]; for (int i = 0; i < columnNames.length; i++) { cols[i] = new Column(columnNames[i], Value.STRING); } index.setRecursive(true); createException = null; } } setColumns(cols); if (getId() != 0) { addViewToTables(); } }
private ResultDiskBuffer(ResultDiskBuffer parent) { this.parent = parent; rowBuff = Data.create(parent.rowBuff.getHandler(), Constants.DEFAULT_PAGE_SIZE); file = parent.file; if (parent.tapes != null) { tapes = New.arrayList(); for (ResultDiskTape t : parent.tapes) { ResultDiskTape t2 = new ResultDiskTape(); t2.pos = t2.start = t.start; t2.end = t.end; tapes.add(t2); } } else { tapes = null; } if (parent.mainTape != null) { mainTape = new ResultDiskTape(); mainTape.pos = FileStore.HEADER_LENGTH; mainTape.start = parent.mainTape.start; mainTape.end = parent.mainTape.end; } else { mainTape = null; } sort = parent.sort; columnCount = parent.columnCount; maxBufferSize = parent.maxBufferSize; }
public HashSet<Table> getTables() { HashSet<Table> set = New.hashSet(); for (TableFilter filter : filters) { set.add(filter.getTable()); } return set; }
private ArrayList<String> mapColumnNames(Object[] columns) { ArrayList<String> columnNames = New.arrayList(); for (Object column : columns) { columnNames.add(getColumnName(column)); } return columnNames; }
public void reset() throws SQLException { log("reset;"); DatabaseMetaData meta = conn.getMetaData(); Statement stat = conn.createStatement(); ArrayList<String> tables = New.arrayList(); ResultSet rs = meta.getTables(null, null, null, new String[] {"TABLE"}); while (rs.next()) { String schemaName = rs.getString("TABLE_SCHEM"); if (!"INFORMATION_SCHEMA".equals(schemaName)) { tables.add(rs.getString("TABLE_NAME")); } } while (tables.size() > 0) { int dropped = 0; for (int i = 0; i < tables.size(); i++) { try { String table = tables.get(i); stat.execute("DROP TABLE " + table); dropped++; tables.remove(i); i--; } catch (SQLException e) { // maybe a referential integrity } } // could not drop any table and still tables to drop if (dropped == 0 && tables.size() > 0) { throw new AssertionError("Cannot drop " + tables); } } }
public <A> QueryWhere<T> where(Filter filter) { HashMap<String, Object> fieldMap = New.hashMap(); for (Field f : filter.getClass().getDeclaredFields()) { f.setAccessible(true); try { Object obj = f.get(filter); if (obj == from.getAlias()) { List<TableDefinition.FieldDefinition> fields = from.getAliasDefinition().getFields(); String name = f.getName(); for (TableDefinition.FieldDefinition field : fields) { String n = name + "." + field.field.getName(); Object o = field.field.get(obj); fieldMap.put(n, o); } } fieldMap.put(f.getName(), f.get(filter)); } catch (Exception e) { throw new RuntimeException(e); } } Token filterCode = new ClassReader().decompile(filter, fieldMap, "where"); // String filterQuery = filterCode.toString(); conditions.add(filterCode); return new QueryWhere<T>(this); }
@SuppressWarnings("unchecked") private <X> List<X> selectSimple(X x, boolean distinct) { SQLStatement stat = getSelectStatement(distinct); appendSQL(stat, x); appendFromWhere(stat); ResultSet rs = stat.executeQuery(); List<X> result = New.arrayList(); Statement s = null; try { s = rs.getStatement(); while (rs.next()) { try { X value; Object o = rs.getObject(1); int convertHereIsProbablyWrong; if (Clob.class.isAssignableFrom(o.getClass())) { value = (X) ClassUtils.convert(o, String.class); } else { value = (X) o; } result.add(value); } catch (Exception e) { throw new RuntimeException(e); } } } catch (SQLException e) { throw new RuntimeException(e); } finally { JdbcUtils.closeSilently(rs); JdbcUtils.closeSilently(s); } return result; }
private void testIterateOverChanges() { String fileName = getBaseDir() + "/testIterate.h3"; FileUtils.delete(fileName); MVStore s = openStore(fileName); s.setMaxPageSize(6); MVMap<Integer, String> m = s.openMap("data", Integer.class, String.class); for (int i = 0; i < 100; i++) { m.put(i, "Hi"); } s.incrementVersion(); s.store(); for (int i = 20; i < 40; i++) { assertEquals("Hi", m.put(i, "Hello")); } long old = s.getCurrentVersion(); s.incrementVersion(); for (int i = 10; i < 15; i++) { m.put(i, "Hallo"); } m.put(50, "Hallo"); for (int i = 90; i < 93; i++) { assertEquals("Hi", m.remove(i)); } assertEquals(null, m.put(100, "Hallo")); Iterator<Integer> it = m.changeIterator(old); ArrayList<Integer> list = New.arrayList(); while (it.hasNext()) { list.add(it.next()); } assertEquals("[10, 11, 12, 13, 14, 50, 100, 90, 91, 92]", list.toString()); s.close(); }
/** * Defines an index with the specified column names. * * @param type the index type (STANDARD, HASH, UNIQUE, UNIQUE_HASH) * @param columnNames the ordered list of column names */ void addIndex(IndexType type, List<String> columnNames) { IndexDefinition index = new IndexDefinition(); index.indexName = tableName + "_" + indexes.size(); index.columnNames = New.arrayList(columnNames); index.type = type; indexes.add(index); }
private static void registerDefaultProviders() { if (providers == null || defaultProvider == null) { Map<String, FilePath> map = Collections.synchronizedMap(New.<String, FilePath>hashMap()); // 默认是org.h2.store.fs.FilePathDisk, 所以这里不包含它 // 但是少了org.h2.store.fs.FilePathRec、org.h2.mvstore.cache.FilePathCache // 不过org.h2.store.fs.FilePathRec是通过org.h2.store.fs.FilePath.register(FilePath)这个方法注册 // 见org.h2.store.fs.FilePathRec.register(), // 在org.h2.engine.ConnectionInfo.ConnectionInfo(String, Properties)调用它了 for (String c : new String[] { "org.h2.store.fs.FilePathDisk", "org.h2.store.fs.FilePathMem", "org.h2.store.fs.FilePathMemLZF", "org.h2.store.fs.FilePathNioMem", "org.h2.store.fs.FilePathNioMemLZF", "org.h2.store.fs.FilePathSplit", "org.h2.store.fs.FilePathNio", "org.h2.store.fs.FilePathNioMapped", "org.h2.store.fs.FilePathZip" }) { try { FilePath p = (FilePath) Class.forName(c).newInstance(); map.put(p.getScheme(), p); if (defaultProvider == null) { defaultProvider = p; } } catch (Exception e) { // ignore - the files may be excluded in purpose } } providers = map; } }
/** * Define a primary key by the specified column names. * * @param columnNames the ordered list of column names */ void setPrimaryKey(List<String> columnNames) { primaryKeyColumnNames = New.arrayList(columnNames); // set isPrimaryKey flag for all field definitions for (FieldDefinition fieldDefinition : fieldMap.values()) { fieldDefinition.isPrimaryKey = this.primaryKeyColumnNames.contains(fieldDefinition.columnName); } }
/** * Remember that the given LOB value must be un-linked (disconnected from the table) at commit. * * @param v the value */ public void unlinkAtCommit(Value v) { if (SysProperties.CHECK && !v.isLinked()) { DbException.throwInternalError(); } if (unlinkLobMap == null) { unlinkLobMap = New.hashMap(); } unlinkLobMap.put(v.toString(), v); }
/** * Keep a collection of the columns to pass to update if a duplicate key happens, for MySQL-style * INSERT ... ON DUPLICATE KEY UPDATE .... * * @param column the column * @param expression the expression */ public void addAssignmentForDuplicate(Column column, Expression expression) { if (duplicateKeyAssignmentMap == null) { duplicateKeyAssignmentMap = New.hashMap(); } if (duplicateKeyAssignmentMap.containsKey(column)) { throw DbException.get(ErrorCode.DUPLICATE_COLUMN_NAME_1, column.getName()); } duplicateKeyAssignmentMap.put(column, expression); }
List<IndexDefinition> getIndexes(IndexType type) { List<IndexDefinition> list = New.arrayList(); for (IndexDefinition def : indexes) { if (def.type.equals(type)) { list.add(def); } } return list; }
/** * Open a copy of the map in read-only mode. * * @return the opened map */ protected MVMap<K, V> openReadOnly() { MVMap<K, V> m = new MVMap<K, V>(keyType, valueType); m.readOnly = true; HashMap<String, String> config = New.hashMap(); config.put("id", String.valueOf(id)); config.put("createVersion", String.valueOf(createVersion)); m.init(store, config); m.root = root; return m; }
ArrayList<InDoubtTransaction> getInDoubtTransactions() { ArrayList<InDoubtTransaction> list = New.arrayList(); for (SessionState state : sessionStates.values()) { PageStoreInDoubtTransaction in = state.inDoubtTransaction; if (in != null) { list.add(in); } } return list; }
/** * Commit the current transaction. If the statement was not a data definition statement, and if * there are temporary tables that should be dropped or truncated at commit, this is done as well. * * @param ddl if the statement was a data definition statement */ public void commit(boolean ddl) { checkCommitRollback(); currentTransactionName = null; transactionStart = 0; if (transaction != null) { // increment the data mod count, so that other sessions // see the changes // TODO should not rely on locking if (locks.size() > 0) { for (int i = 0, size = locks.size(); i < size; i++) { Table t = locks.get(i); if (t instanceof MVTable) { ((MVTable) t).commit(); } } } transaction.commit(); transaction = null; } if (containsUncommitted()) { // need to commit even if rollback is not possible // (create/drop table and so on) database.commit(this); } removeTemporaryLobs(true); if (undoLog.size() > 0) { // commit the rows when using MVCC if (database.isMultiVersion()) { ArrayList<Row> rows = New.arrayList(); synchronized (database) { while (undoLog.size() > 0) { UndoLogRecord entry = undoLog.getLast(); entry.commit(); rows.add(entry.getRow()); undoLog.removeLast(false); } for (int i = 0, size = rows.size(); i < size; i++) { Row r = rows.get(i); r.commit(); } } } undoLog.clear(); } if (!ddl) { // do not clean the temp tables if the last command was a // create/drop cleanTempTables(false); if (autoCommitAtTransactionEnd) { autoCommit = true; autoCommitAtTransactionEnd = false; } } endTransaction(); }
public DbSettings getDbSettings() { DbSettings defaultSettings = DbSettings.getDefaultSettings(); HashMap<String, String> s = New.hashMap(); for (Object k : prop.keySet()) { String key = k.toString(); if (!isKnownSetting(key) && defaultSettings.containsKey(key)) { s.put(key, prop.getProperty(key)); } } return DbSettings.getInstance(s); }
private void checkDefaultReferencesTable(Expression defaultExpression) { if (defaultExpression == null) { return; } HashSet<DbObject> dependencies = New.hashSet(); ExpressionVisitor visitor = ExpressionVisitor.getDependenciesVisitor(dependencies); defaultExpression.isEverything(visitor); if (dependencies.contains(table)) { throw DbException.get(ErrorCode.COLUMN_IS_REFERENCED_1, defaultExpression.getSQL()); } }
public ArrayList<FilePath> newDirectoryStream() { List<FilePath> list = getBase().newDirectoryStream(); ArrayList<FilePath> newList = New.arrayList(); for (int i = 0, size = list.size(); i < size; i++) { FilePath f = list.get(i); if (!f.getName().endsWith(PART_SUFFIX)) { newList.add(wrap(f)); } } return newList; }
/** * Remember the result set and close it as soon as the transaction is committed (if it needs to be * closed). This is done to delete temporary files as soon as possible, and free object ids of * temporary tables. * * @param result the temporary result set */ public void addTemporaryResult(LocalResult result) { if (!result.needToClose()) { return; } if (temporaryResults == null) { temporaryResults = New.hashSet(); } if (temporaryResults.size() < 100) { // reference at most 100 result sets to avoid memory problems temporaryResults.add(result); } }
/** * Get a random column that can be used in a condition. * * @return the column */ Column getRandomConditionColumn() { ArrayList<Column> list = New.arrayList(); for (Column col : columns) { if (Column.isConditionType(config, col.getType())) { list.add(col); } } if (list.size() == 0) { return null; } return list.get(config.random().getInt(list.size())); }
/** * Get a random column of the specified type. * * @param type the type * @return the column or null if no such column was found */ Column getRandomColumnOfType(int type) { ArrayList<Column> list = New.arrayList(); for (Column col : columns) { if (col.getType() == type) { list.add(col); } } if (list.size() == 0) { return null; } return list.get(config.random().getInt(list.size())); }
private long[] getMemoryUsed(int count, int size) { long hash, tree, mv; ArrayList<Map<Integer, String>> mapList; long mem; mapList = New.arrayList(); mem = getMemory(); for (int i = 0; i < count; i++) { mapList.add(new HashMap<Integer, String>(size)); } addEntries(mapList, size); hash = getMemory() - mem; mapList.size(); mapList = New.arrayList(); mem = getMemory(); for (int i = 0; i < count; i++) { mapList.add(new TreeMap<Integer, String>()); } addEntries(mapList, size); tree = getMemory() - mem; mapList.size(); mapList = New.arrayList(); mem = getMemory(); MVStore store = MVStore.open(null); for (int i = 0; i < count; i++) { Map<Integer, String> map = store.openMap("t" + i); mapList.add(map); } addEntries(mapList, size); mv = getMemory() - mem; mapList.size(); trace("hash: " + hash / 1024 / 1024 + " mb"); trace("tree: " + tree / 1024 / 1024 + " mb"); trace("mv: " + mv / 1024 / 1024 + " mb"); return new long[] {hash, tree, mv}; }
/** * Adds a statement to the batch. * * @param sql the SQL statement */ public void addBatch(String sql) throws SQLException { try { debugCodeCall("addBatch", sql); checkClosed(); sql = JdbcConnection.translateSQL(sql, escapeProcessing); if (batchCommands == null) { batchCommands = New.arrayList(); } batchCommands.add(sql); } catch (Exception e) { throw logAndConvert(e); } }
public final Value[] getParameterValues() { ArrayList<Parameter> list = getParameters(); if (list == null) { list = New.arrayList(); } int size = list.size(); Value[] params = new Value[size]; for (int i = 0; i < size; i++) { Value v = list.get(i).getParamValue(); params[i] = v; } return params; }
private void queryGroupSorted(int columnCount, ResultTarget result) { int rowNumber = 0; setCurrentRowNumber(0); Value[] previousKeyValues = null; while (topTableFilter.next()) { setCurrentRowNumber(rowNumber + 1); if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session))) { rowNumber++; Value[] keyValues = new Value[groupIndex.length]; // update group for (int i = 0; i < groupIndex.length; i++) { int idx = groupIndex[i]; Expression expr = expressions.get(idx); keyValues[i] = expr.getValue(session); } if (previousKeyValues == null) { previousKeyValues = keyValues; currentGroup = New.hashMap(); } else if (!Arrays.equals(previousKeyValues, keyValues)) { addGroupSortedRow(previousKeyValues, columnCount, result); previousKeyValues = keyValues; currentGroup = New.hashMap(); } currentGroupRowId++; for (int i = 0; i < columnCount; i++) { if (groupByExpression == null || !groupByExpression[i]) { Expression expr = expressions.get(i); expr.updateAggregate(session); } } } } if (previousKeyValues != null) { addGroupSortedRow(previousKeyValues, columnCount, result); } }