summaryrefslogtreecommitdiffstats
path: root/apps/comments/l10n
diff options
context:
space:
mode:
Diffstat (limited to 'apps/comments/l10n')
-rw-r--r--apps/comments/l10n/.gitkeep0
1 files changed, 0 insertions, 0 deletions
diff --git a/apps/comments/l10n/.gitkeep b/apps/comments/l10n/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/apps/comments/l10n/.gitkeep
ass="p">); for(Column c : autoCols) { if(!autoTypes.add(c.getType())) { throw new IllegalArgumentException( "Can have at most one AutoNumber column of type " + c.getType() + " per table"); } } } //Write the tdef page to disk. int tdefPageNumber = Table.writeTableDefinition(columns, _pageChannel, _format); //Add this table to our internal list. addTable(name, Integer.valueOf(tdefPageNumber)); //Add this table to system tables addToSystemCatalog(name, tdefPageNumber); addToAccessControlEntries(tdefPageNumber); } /** * Finds all the relationships in the database between the given tables. */ public List<Relationship> getRelationships(Table table1, Table table2) throws IOException { // the relationships table does not get loaded until first accessed if(_relationships == null) { _relationships = getSystemTable(TABLE_SYSTEM_RELATIONSHIPS); if(_relationships == null) { throw new IOException("Could not find system relationships table"); } } int nameCmp = table1.getName().compareTo(table2.getName()); if(nameCmp == 0) { throw new IllegalArgumentException("Must provide two different tables"); } if(nameCmp > 0) { // we "order" the two tables given so that we will return a collection // of relationships in the same order regardless of whether we are given // (TableFoo, TableBar) or (TableBar, TableFoo). Table tmp = table1; table1 = table2; table2 = tmp; } List<Relationship> relationships = new ArrayList<Relationship>(); Cursor cursor = createCursorWithOptionalIndex( _relationships, REL_COL_FROM_TABLE, table1.getName()); collectRelationships(cursor, table1, table2, relationships); cursor = createCursorWithOptionalIndex( _relationships, REL_COL_TO_TABLE, table1.getName()); collectRelationships(cursor, table2, table1, relationships); return relationships; } /** * Finds all the queries in the database. */ public List<Query> getQueries() throws IOException { // the queries table does not get loaded until first accessed if(_queries == null) { _queries = getSystemTable(TABLE_SYSTEM_QUERIES); if(_queries == null) { throw new IOException("Could not find system queries table"); } } // find all the queries from the system catalog List<Map<String,Object>> queryInfo = new ArrayList<Map<String,Object>>(); Map<Integer,List<Query.Row>> queryRowMap = new HashMap<Integer,List<Query.Row>>(); for(Map<String,Object> row : Cursor.createCursor(_systemCatalog).iterable( SYSTEM_CATALOG_QUERY_COLUMNS)) { String name = (String) row.get(CAT_COL_NAME); if (name != null && TYPE_QUERY.equals(row.get(CAT_COL_TYPE))) { queryInfo.add(row); Integer id = (Integer)row.get(CAT_COL_ID); queryRowMap.put(id, new ArrayList<Query.Row>()); } } // find all the query rows for(Map<String,Object> row : Cursor.createCursor(_queries)) { Query.Row queryRow = new Query.Row(row); List<Query.Row> queryRows = queryRowMap.get(queryRow.objectId); if(queryRows == null) { LOG.warn("Found rows for query with id " + queryRow.objectId + " missing from system catalog"); continue; } queryRows.add(queryRow); } // lastly, generate all the queries List<Query> queries = new ArrayList<Query>(); for(Map<String,Object> row : queryInfo) { String name = (String) row.get(CAT_COL_NAME); Integer id = (Integer)row.get(CAT_COL_ID); int flags = (Integer)row.get(CAT_COL_FLAGS); List<Query.Row> queryRows = queryRowMap.get(id); queries.add(Query.create(flags, name, queryRows, id)); } return queries; } /** * Returns a reference to <i>any</i> available table in this access * database, including system tables. * <p> * Warning, this method is not designed for common use, only for the * occassional time when access to a system table is necessary. Messing * with system tables can strip the paint off your house and give your whole * family a permanent, orange afro. You have been warned. * * @param tableName Table name, may be a system table * @return The table, or {@code null} if it doesn't exist */ public Table getSystemTable(String tableName) throws IOException { for(Map<String,Object> row : Cursor.createCursor(_systemCatalog).iterable( SYSTEM_CATALOG_COLUMNS)) { String name = (String) row.get(CAT_COL_NAME); if (tableName.equalsIgnoreCase(name) && TYPE_TABLE.equals(row.get(CAT_COL_TYPE))) { Integer pageNumber = (Integer) row.get(CAT_COL_ID); if(pageNumber != null) { return readTable(name, pageNumber, defaultUseBigIndex()); } } } return null; } /** * Finds the relationships matching the given from and to tables from the * given cursor and adds them to the given list. */ private void collectRelationships( Cursor cursor, Table fromTable, Table toTable, List<Relationship> relationships) { for(Map<String,Object> row : cursor) { String fromName = (String)row.get(REL_COL_FROM_TABLE); String toName = (String)row.get(REL_COL_TO_TABLE); if(fromTable.getName().equals(fromName) && toTable.getName().equals(toName)) { String relName = (String)row.get(REL_COL_NAME); // found more info for a relationship. see if we already have some // info for this relationship Relationship rel = null; for(Relationship tmp : relationships) { if(tmp.getName().equals(relName)) { rel = tmp; break; } } if(rel == null) { // new relationship int numCols = (Integer)row.get(REL_COL_COLUMN_COUNT); int flags = (Integer)row.get(REL_COL_FLAGS); rel = new Relationship(relName, fromTable, toTable, flags, numCols); relationships.add(rel); } // add column info int colIdx = (Integer)row.get(REL_COL_COLUMN_INDEX); Column fromCol = fromTable.getColumn( (String)row.get(REL_COL_FROM_COLUMN)); Column toCol = toTable.getColumn( (String)row.get(REL_COL_TO_COLUMN)); rel.getFromColumns().set(colIdx, fromCol); rel.getToColumns().set(colIdx, toCol); } } } /** * Add a new table to the system catalog * @param name Table name * @param pageNumber Page number that contains the table definition */ private void addToSystemCatalog(String name, int pageNumber) throws IOException { Object[] catalogRow = new Object[_systemCatalog.getColumnCount()]; int idx = 0; Date creationTime = new Date(); for (Iterator<Column> iter = _systemCatalog.getColumns().iterator(); iter.hasNext(); idx++) { Column col = iter.next(); if (CAT_COL_ID.equals(col.getName())) { catalogRow[idx] = Integer.valueOf(pageNumber); } else if (CAT_COL_NAME.equals(col.getName())) { catalogRow[idx] = name; } else if (CAT_COL_TYPE.equals(col.getName())) { catalogRow[idx] = TYPE_TABLE; } else if (CAT_COL_DATE_CREATE.equals(col.getName()) || CAT_COL_DATE_UPDATE.equals(col.getName())) { catalogRow[idx] = creationTime; } else if (CAT_COL_PARENT_ID.equals(col.getName())) { catalogRow[idx] = _tableParentId; } else if (CAT_COL_FLAGS.equals(col.getName())) { catalogRow[idx] = Integer.valueOf(0); } else if (CAT_COL_OWNER.equals(col.getName())) { byte[] owner = new byte[2]; catalogRow[idx] = owner; owner[0] = (byte) 0xcf; owner[1] = (byte) 0x5f; } } _systemCatalog.addRow(catalogRow); } /** * Add a new table to the system's access control entries * @param pageNumber Page number that contains the table definition */ private void addToAccessControlEntries(int pageNumber) throws IOException { if(_newTableSIDs.isEmpty()) { initNewTableSIDs(); } Column acmCol = _accessControlEntries.getColumn(ACE_COL_ACM); Column inheritCol = _accessControlEntries.getColumn(ACE_COL_F_INHERITABLE); Column objIdCol = _accessControlEntries.getColumn(ACE_COL_OBJECT_ID); Column sidCol = _accessControlEntries.getColumn(ACE_COL_SID); // construct a collection of ACE entries mimicing those of our parent, the // "Tables" system object List<Object[]> aceRows = new ArrayList<Object[]>(_newTableSIDs.size()); for(byte[] sid : _newTableSIDs) { Object[] aceRow = new Object[_accessControlEntries.getColumnCount()]; aceRow[acmCol.getColumnIndex()] = SYS_FULL_ACCESS_ACM; aceRow[inheritCol.getColumnIndex()] = Boolean.FALSE; aceRow[objIdCol.getColumnIndex()] = Integer.valueOf(pageNumber); aceRow[sidCol.getColumnIndex()] = sid; aceRows.add(aceRow); } _accessControlEntries.addRows(aceRows); } /** * Determines the collection of SIDs which need to be added to new tables. */ private void initNewTableSIDs() throws IOException { // search for ACEs matching the tableParentId. use the index on the // objectId column if found (should be there) Cursor cursor = createCursorWithOptionalIndex( _accessControlEntries, ACE_COL_OBJECT_ID, _tableParentId); for(Map<String, Object> row : cursor) { Integer objId = (Integer)row.get(ACE_COL_OBJECT_ID); if(_tableParentId.equals(objId)) { _newTableSIDs.add((byte[])row.get(ACE_COL_SID)); } } if(_newTableSIDs.isEmpty()) { // if all else fails, use the hard-coded default _newTableSIDs.add(SYS_DEFAULT_SID); } } /** * Reads a table with the given name from the given pageNumber. */ private Table readTable(String name, int pageNumber, boolean useBigIndex) throws IOException { _pageChannel.readPage(_buffer, pageNumber); byte pageType = _buffer.get(0); if (pageType != PageTypes.TABLE_DEF) { throw new IOException("Looking for " + name + " at page " + pageNumber + ", but page type is " + pageType); } return new Table(this, _buffer, pageNumber, name, useBigIndex); } /** * Creates a Cursor restricted to the given column value if possible (using * an existing index), otherwise a simple table cursor. */ private static Cursor createCursorWithOptionalIndex( Table table, String colName, Object colValue) throws IOException { try { return new CursorBuilder(table) .setIndexByColumns(table.getColumn(colName)) .setSpecificEntry(colValue) .toCursor(); } catch(IllegalArgumentException e) { LOG.info("Could not find expected index on table " + table.getName()); } // use table scan instead return Cursor.createCursor(table); } /** * Copy an existing JDBC ResultSet into a new table in this database * @param name Name of the new table to create * @param source ResultSet to copy from */ public void copyTable(String name, ResultSet source) throws SQLException, IOException { copyTable(name, source, SimpleImportFilter.INSTANCE); } /** * Copy an existing JDBC ResultSet into a new table in this database * @param name Name of the new table to create * @param source ResultSet to copy from * @param filter valid import filter */ public void copyTable(String name, ResultSet source, ImportFilter filter) throws SQLException, IOException { ResultSetMetaData md = source.getMetaData(); List<Column> columns = new LinkedList<Column>(); for (int i = 1; i <= md.getColumnCount(); i++) { Column column = new Column(); column.setName(escape(md.getColumnName(i))); int lengthInUnits = md.getColumnDisplaySize(i); column.setSQLType(md.getColumnType(i), lengthInUnits); DataType type = column.getType(); // we check for isTrueVariableLength here to avoid setting the length // for a NUMERIC column, which pretends to be var-len, even though it // isn't if(type.isTrueVariableLength() && !type.isLongValue()) { column.setLengthInUnits((short)lengthInUnits); } if(type.getHasScalePrecision()) { int scale = md.getScale(i); int precision = md.getPrecision(i); if(type.isValidScale(scale)) { column.setScale((byte)scale); } if(type.isValidPrecision(precision)) { column.setPrecision((byte)precision); } } columns.add(column); } createTable(escape(name), filter.filterColumns(columns, md)); Table table = getTable(escape(name)); List<Object[]> rows = new ArrayList<Object[]>(COPY_TABLE_BATCH_SIZE); while (source.next()) { Object[] row = new Object[md.getColumnCount()]; for (int i = 0; i < row.length; i++) { row[i] = source.getObject(i + 1); } rows.add(filter.filterRow(row)); if (rows.size() == COPY_TABLE_BATCH_SIZE) { table.addRows(rows); rows.clear(); } } if (rows.size() > 0) { table.addRows(rows); } } /** * Copy a delimited text file into a new table in this database * @param name Name of the new table to create * @param f Source file to import * @param delim Regular expression representing the delimiter string. */ public void importFile(String name, File f, String delim) throws IOException { importFile(name, f, delim, SimpleImportFilter.INSTANCE); } /** * Copy a delimited text file into a new table in this database * @param name Name of the new table to create * @param f Source file to import * @param delim Regular expression representing the delimiter string. * @param filter valid import filter */ public void importFile(String name, File f, String delim, ImportFilter filter) throws IOException { BufferedReader in = null; try { in = new BufferedReader(new FileReader(f)); importReader(name, in, delim, filter); } finally { if (in != null) { try { in.close(); } catch (IOException ex) { LOG.warn("Could not close file " + f.getAbsolutePath(), ex); } } } } /** * Copy a delimited text file into a new table in this database * @param name Name of the new table to create * @param in Source reader to import * @param delim Regular expression representing the delimiter string. */ public void importReader(String name, BufferedReader in, String delim) throws IOException { importReader(name, in, delim, SimpleImportFilter.INSTANCE); } /** * Copy a delimited text file into a new table in this database * @param name Name of the new table to create * @param in Source reader to import * @param delim Regular expression representing the delimiter string. * @param filter valid import filter */ public void importReader(String name, BufferedReader in, String delim, ImportFilter filter) throws IOException { String line = in.readLine(); if (line == null || line.trim().length() == 0) { return; } String tableName = escape(name); int counter = 0; while(getTable(tableName) != null) { tableName = escape(name + (counter++)); } List<Column> columns = new LinkedList<Column>(); String[] columnNames = line.split(delim); for (int i = 0; i < columnNames.length; i++) { columns.add(new ColumnBuilder(escape(columnNames[i]), DataType.TEXT) .setLength((short)DataType.TEXT.getMaxSize()) .toColumn()); } try { createTable(tableName, filter.filterColumns(columns, null)); Table table = getTable(tableName); List<Object[]> rows = new ArrayList<Object[]>(COPY_TABLE_BATCH_SIZE); while ((line = in.readLine()) != null) { // // Handle the situation where the end of the line // may have null fields. We always want to add the // same number of columns to the table each time. // Object[] data = Table.dupeRow(line.split(delim), columnNames.length); rows.add(filter.filterRow(data)); if (rows.size() == COPY_TABLE_BATCH_SIZE) { table.addRows(rows); rows.clear(); } } if (rows.size() > 0) { table.addRows(rows); } } catch(SQLException e) { throw (IOException)new IOException(e.getMessage()).initCause(e); } } /** * Flushes any current changes to the database file to disk. */ public void flush() throws IOException { _pageChannel.flush(); } /** * Close the database file */ public void close() throws IOException { _pageChannel.close(); } /** * @return A table or column name escaped for Access */ private String escape(String s) { if (isReservedWord(s)) { return ESCAPE_PREFIX + s; } return s; } /** * @return {@code true} if the given string is a reserved word, * {@code false} otherwise */ public static boolean isReservedWord(String s) { return RESERVED_WORDS.contains(s.toLowerCase()); } /** * Validates an identifier name. */ public static void validateIdentifierName(String name, int maxLength, String identifierType) { if((name == null) || (name.trim().length() == 0)) { throw new IllegalArgumentException( identifierType + " must have non-empty name"); } if(name.length() > maxLength) { throw new IllegalArgumentException( identifierType + " name is longer than max length of " + maxLength + ": " + name); } } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } /** * Adds a table to the _tableLookup and resets the _tableNames set */ private void addTable(String tableName, Integer pageNumber) { _tableLookup.put(toLookupTableName(tableName), new TableInfo(pageNumber, tableName)); // clear this, will be created next time needed _tableNames = null; } /** * @return the tableInfo of the given table, if any */ private TableInfo lookupTable(String tableName) { return _tableLookup.get(toLookupTableName(tableName)); } /** * @return a string usable in the _tableLookup map. */ private String toLookupTableName(String tableName) { return ((tableName != null) ? tableName.toUpperCase() : null); } /** * Returns {@code true} if "big index support" has been enabled explicity on * the this Database or via a system property, {@code false} otherwise. */ public boolean defaultUseBigIndex() { return doUseBigIndex() || Boolean.getBoolean(USE_BIG_INDEX_PROPERTY); } /** * Utility class for storing table page number and actual name. */ private static class TableInfo { public final Integer pageNumber; public final String tableName; private TableInfo(Integer newPageNumber, String newTableName) { pageNumber = newPageNumber; tableName = newTableName; } } /** * Table iterator for this database, unmodifiable. */ private class TableIterator implements Iterator<Table> { private Iterator<String> _tableNameIter; private TableIterator() { _tableNameIter = getTableNames().iterator(); } public boolean hasNext() { return _tableNameIter.hasNext(); } public void remove() { throw new UnsupportedOperationException(); } public Table next() { if(!hasNext()) { throw new NoSuchElementException(); } try { return getTable(_tableNameIter.next()); } catch(IOException e) { throw new IllegalStateException(e); } } } }