* add reason to unsupop throws for indexes
* remove static methods in CursorImpl/IndexCursorImpl
* create ComplexValue.Id and keep RowId
-- remove DatabaseImpl from util classes
+* remove DatabaseImpl from util classes
- remove unnecessary iterator class from impl classes?
- merge latest changes from main branch
+- remove iterable methods from impls if unused?
* public api final cleanup:
* Database
+
+- changes
+ - simple index support gone
+ - foreign key constraints enforced by default
+ - "main" classes became interfaces
+ - advanced functionality still remains in impl classes
+ - all new instance construction via builders
+ - iterable methods went away, iterable builder
+ - util classes moved to util package
+ - Row is now an interface
+
}
/**
- * Escapes the new column's name using {@link DatabaseImpl#escapeIdentifier}.
+ * Escapes the new column's name using {@link TableBuilder#escapeIdentifier}.
*/
- public ColumnBuilder escapeName()
- {
- _name = DatabaseImpl.escapeIdentifier(_name);
+ public ColumnBuilder escapeName() {
+ _name = TableBuilder.escapeIdentifier(_name);
return this;
}
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import com.healthmarketscience.jackcess.impl.DatabaseImpl;
*/
public class TableBuilder {
+ /** Prefix for column or table names that are reserved words */
+ private static final String ESCAPE_PREFIX = "x";
+
+ /* nested class for lazy loading */
+ private static final class ReservedWords {
+ /**
+ * All of the reserved words in Access that should be escaped when creating
+ * table or column names
+ */
+ private static final Set<String> VALUES =
+ new HashSet<String>(Arrays.asList(
+ "add", "all", "alphanumeric", "alter", "and", "any", "application", "as",
+ "asc", "assistant", "autoincrement", "avg", "between", "binary", "bit",
+ "boolean", "by", "byte", "char", "character", "column", "compactdatabase",
+ "constraint", "container", "count", "counter", "create", "createdatabase",
+ "createfield", "creategroup", "createindex", "createobject", "createproperty",
+ "createrelation", "createtabledef", "createuser", "createworkspace",
+ "currency", "currentuser", "database", "date", "datetime", "delete",
+ "desc", "description", "disallow", "distinct", "distinctrow", "document",
+ "double", "drop", "echo", "else", "end", "eqv", "error", "exists", "exit",
+ "false", "field", "fields", "fillcache", "float", "float4", "float8",
+ "foreign", "form", "forms", "from", "full", "function", "general",
+ "getobject", "getoption", "gotopage", "group", "group by", "guid", "having",
+ "idle", "ieeedouble", "ieeesingle", "if", "ignore", "imp", "in", "index",
+ "indexes", "inner", "insert", "inserttext", "int", "integer", "integer1",
+ "integer2", "integer4", "into", "is", "join", "key", "lastmodified", "left",
+ "level", "like", "logical", "logical1", "long", "longbinary", "longtext",
+ "macro", "match", "max", "min", "mod", "memo", "module", "money", "move",
+ "name", "newpassword", "no", "not", "null", "number", "numeric", "object",
+ "oleobject", "off", "on", "openrecordset", "option", "or", "order", "outer",
+ "owneraccess", "parameter", "parameters", "partial", "percent", "pivot",
+ "primary", "procedure", "property", "queries", "query", "quit", "real",
+ "recalc", "recordset", "references", "refresh", "refreshlink",
+ "registerdatabase", "relation", "repaint", "repairdatabase", "report",
+ "reports", "requery", "right", "screen", "section", "select", "set",
+ "setfocus", "setoption", "short", "single", "smallint", "some", "sql",
+ "stdev", "stdevp", "string", "sum", "table", "tabledef", "tabledefs",
+ "tableid", "text", "time", "timestamp", "top", "transform", "true", "type",
+ "union", "unique", "update", "user", "value", "values", "var", "varp",
+ "varbinary", "varchar", "where", "with", "workspace", "xor", "year", "yes",
+ "yesno"));
+ }
+
+
/** name of the new table */
private String _name;
/** columns for the new table */
_name = name;
_escapeIdentifiers = escapeIdentifiers;
if(_escapeIdentifiers) {
- _name = DatabaseImpl.escapeIdentifier(_name);
+ _name = escapeIdentifier(_name);
}
}
return this;
}
+ /**
+ * Adds the Columns to the new table.
+ */
+ public TableBuilder addColumns(Collection<? extends ColumnBuilder> columns) {
+ if(columns != null) {
+ for(ColumnBuilder col : columns) {
+ addColumn(col);
+ }
+ }
+ return this;
+ }
+
/**
* Adds an IndexBuilder to the new table.
*/
public TableBuilder addIndex(IndexBuilder index) {
if(_escapeIdentifiers) {
- index.setName(DatabaseImpl.escapeIdentifier(index.getName()));
+ index.setName(escapeIdentifier(index.getName()));
for(IndexBuilder.Column col : index.getColumns()) {
- col.setName(DatabaseImpl.escapeIdentifier(col.getName()));
+ col.setName(escapeIdentifier(col.getName()));
}
}
_indexes.add(index);
}
/**
- * Escapes the new table's name using {@link DatabaseImpl#escapeIdentifier}.
+ * Escapes the new table's name using {@link TableBuilder#escapeIdentifier}.
*/
- public TableBuilder escapeName()
- {
- _name = DatabaseImpl.escapeIdentifier(_name);
+ public TableBuilder escapeName() {
+ _name = escapeIdentifier(_name);
return this;
}
((DatabaseImpl)db).createTable(_name, _columns, _indexes);
return db.getTable(_name);
}
+
+ /**
+ * @return A table or column name escaped for Access
+ * @usage _general_method_
+ */
+ public static String escapeIdentifier(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
+ * @usage _general_method_
+ */
+ public static boolean isReservedWord(String s) {
+ return ReservedWords.VALUES.contains(s.toLowerCase());
+ }
+
}
/** read/write channel access mode */
public static final String RW_CHANNEL_MODE = "rw";
- /** Prefix for column or table names that are reserved words */
- private static final String ESCAPE_PREFIX = "x";
/** Name of the system object that is the parent of all tables */
private static final String SYSTEM_OBJECT_NAME_TABLES = "Tables";
/** Name of the system object that is the parent of all databases */
new HashSet<String>(Arrays.asList(CAT_COL_ID, CAT_COL_PROPS));
- /**
- * All of the reserved words in Access that should be escaped when creating
- * table or column names
- */
- private static final Set<String> RESERVED_WORDS = new HashSet<String>();
- static {
- //Yup, there's a lot.
- RESERVED_WORDS.addAll(Arrays.asList(
- "add", "all", "alphanumeric", "alter", "and", "any", "application", "as",
- "asc", "assistant", "autoincrement", "avg", "between", "binary", "bit",
- "boolean", "by", "byte", "char", "character", "column", "compactdatabase",
- "constraint", "container", "count", "counter", "create", "createdatabase",
- "createfield", "creategroup", "createindex", "createobject", "createproperty",
- "createrelation", "createtabledef", "createuser", "createworkspace",
- "currency", "currentuser", "database", "date", "datetime", "delete",
- "desc", "description", "disallow", "distinct", "distinctrow", "document",
- "double", "drop", "echo", "else", "end", "eqv", "error", "exists", "exit",
- "false", "field", "fields", "fillcache", "float", "float4", "float8",
- "foreign", "form", "forms", "from", "full", "function", "general",
- "getobject", "getoption", "gotopage", "group", "group by", "guid", "having",
- "idle", "ieeedouble", "ieeesingle", "if", "ignore", "imp", "in", "index",
- "indexes", "inner", "insert", "inserttext", "int", "integer", "integer1",
- "integer2", "integer4", "into", "is", "join", "key", "lastmodified", "left",
- "level", "like", "logical", "logical1", "long", "longbinary", "longtext",
- "macro", "match", "max", "min", "mod", "memo", "module", "money", "move",
- "name", "newpassword", "no", "not", "null", "number", "numeric", "object",
- "oleobject", "off", "on", "openrecordset", "option", "or", "order", "outer",
- "owneraccess", "parameter", "parameters", "partial", "percent", "pivot",
- "primary", "procedure", "property", "queries", "query", "quit", "real",
- "recalc", "recordset", "references", "refresh", "refreshlink",
- "registerdatabase", "relation", "repaint", "repairdatabase", "report",
- "reports", "requery", "right", "screen", "section", "select", "set",
- "setfocus", "setoption", "short", "single", "smallint", "some", "sql",
- "stdev", "stdevp", "string", "sum", "table", "tabledef", "tabledefs",
- "tableid", "text", "time", "timestamp", "top", "transform", "true", "type",
- "union", "unique", "update", "user", "value", "values", "var", "varp",
- "varbinary", "varchar", "where", "with", "workspace", "xor", "year", "yes",
- "yesno"
- ));
- }
-
/** the File of the database */
private final File _file;
/** Buffer to hold database pages */
_pageChannel.close();
}
- /**
- * @return A table or column name escaped for Access
- * @usage _general_method_
- */
- public static String escapeIdentifier(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
- * @usage _general_method_
- */
- public static boolean isReservedWord(String s) {
- return RESERVED_WORDS.contains(s.toLowerCase());
- }
-
/**
* Validates an identifier name.
* @usage _advanced_method_
import com.healthmarketscience.jackcess.DataType;
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.Table;
-import com.healthmarketscience.jackcess.impl.DatabaseImpl;
+import com.healthmarketscience.jackcess.TableBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
{
List<ColumnBuilder> columns = new LinkedList<ColumnBuilder>();
for (int i = 1; i <= md.getColumnCount(); i++) {
- ColumnBuilder column = new ColumnBuilder(md.getColumnName(i)).escapeName();
+ ColumnBuilder column = new ColumnBuilder(md.getColumnName(i))
+ .escapeName();
int lengthInUnits = md.getColumnDisplaySize(i);
column.setSQLType(md.getColumnType(i), lengthInUnits);
DataType type = column.getType();
{
ResultSetMetaData md = source.getMetaData();
- name = DatabaseImpl.escapeIdentifier(name);
+ name = TableBuilder.escapeIdentifier(name);
Table table = null;
if(!useExistingTable || ((table = db.getTable(name)) == null)) {
List<ColumnBuilder> columns = toColumns(md);
Pattern delimPat = Pattern.compile(delim);
try {
- name = DatabaseImpl.escapeIdentifier(name);
+ name = TableBuilder.escapeIdentifier(name);
Table table = null;
if(!useExistingTable || ((table = db.getTable(name)) == null)) {
name = baseName + (counter++);
}
- ((DatabaseImpl)db).createTable(name, filter.filterColumns(columns, md));
-
- return db.getTable(name);
+ return new TableBuilder(name)
+ .addColumns(filter.filterColumns(columns, md))
+ .toTable(db);
}
/**