From ce0e678b64dfff14e7dbf5713c940dcbdc1827dd Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Fri, 10 May 2013 02:34:21 +0000 Subject: [PATCH] move escapeIdentifier to more apropos location git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/jackcess-2@717 f203690c-595d-4dc9-a70b-905162fa7fd2 --- TODO.txt | 14 ++- .../jackcess/ColumnBuilder.java | 7 +- .../jackcess/TableBuilder.java | 94 +++++++++++++++++-- .../jackcess/impl/DatabaseImpl.java | 63 ------------- .../jackcess/util/ImportUtil.java | 15 +-- 5 files changed, 111 insertions(+), 82 deletions(-) diff --git a/TODO.txt b/TODO.txt index e32aaec..aaf92f6 100644 --- a/TODO.txt +++ b/TODO.txt @@ -46,9 +46,21 @@ Refactor goals: * 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 + diff --git a/src/java/com/healthmarketscience/jackcess/ColumnBuilder.java b/src/java/com/healthmarketscience/jackcess/ColumnBuilder.java index d66d533..90ddc34 100644 --- a/src/java/com/healthmarketscience/jackcess/ColumnBuilder.java +++ b/src/java/com/healthmarketscience/jackcess/ColumnBuilder.java @@ -235,11 +235,10 @@ public class ColumnBuilder { } /** - * 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; } diff --git a/src/java/com/healthmarketscience/jackcess/TableBuilder.java b/src/java/com/healthmarketscience/jackcess/TableBuilder.java index 63fd7db..9530f51 100644 --- a/src/java/com/healthmarketscience/jackcess/TableBuilder.java +++ b/src/java/com/healthmarketscience/jackcess/TableBuilder.java @@ -29,7 +29,11 @@ package com.healthmarketscience.jackcess; 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; @@ -40,6 +44,50 @@ 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 VALUES = + new HashSet(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 */ @@ -58,7 +106,7 @@ public class TableBuilder { _name = name; _escapeIdentifiers = escapeIdentifiers; if(_escapeIdentifiers) { - _name = DatabaseImpl.escapeIdentifier(_name); + _name = escapeIdentifier(_name); } } @@ -74,14 +122,26 @@ public class TableBuilder { return this; } + /** + * Adds the Columns to the new table. + */ + public TableBuilder addColumns(Collection 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); @@ -108,11 +168,10 @@ public class TableBuilder { } /** - * 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; } @@ -126,5 +185,26 @@ public class TableBuilder { ((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()); + } + } diff --git a/src/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java b/src/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java index 4e8f4fb..e93d3dd 100644 --- a/src/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java +++ b/src/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java @@ -201,8 +201,6 @@ public class DatabaseImpl implements Database /** 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 */ @@ -248,47 +246,6 @@ public class DatabaseImpl implements Database new HashSet(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 RESERVED_WORDS = new HashSet(); - 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 */ @@ -1442,26 +1399,6 @@ public class DatabaseImpl implements Database _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_ diff --git a/src/java/com/healthmarketscience/jackcess/util/ImportUtil.java b/src/java/com/healthmarketscience/jackcess/util/ImportUtil.java index 58b04bb..65ee700 100644 --- a/src/java/com/healthmarketscience/jackcess/util/ImportUtil.java +++ b/src/java/com/healthmarketscience/jackcess/util/ImportUtil.java @@ -45,7 +45,7 @@ import com.healthmarketscience.jackcess.ColumnBuilder; 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; @@ -78,7 +78,8 @@ public class ImportUtil { List columns = new LinkedList(); 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(); @@ -168,7 +169,7 @@ public class ImportUtil { ResultSetMetaData md = source.getMetaData(); - name = DatabaseImpl.escapeIdentifier(name); + name = TableBuilder.escapeIdentifier(name); Table table = null; if(!useExistingTable || ((table = db.getTable(name)) == null)) { List columns = toColumns(md); @@ -457,7 +458,7 @@ public class ImportUtil Pattern delimPat = Pattern.compile(delim); try { - name = DatabaseImpl.escapeIdentifier(name); + name = TableBuilder.escapeIdentifier(name); Table table = null; if(!useExistingTable || ((table = db.getTable(name)) == null)) { @@ -607,9 +608,9 @@ public class ImportUtil 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); } /** -- 2.39.5