From 16d611821a3b6cba866ab596cd5a53b3533e68f8 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Sat, 19 Jul 2008 01:42:54 +0000 Subject: [PATCH] Add some more limit checking into table creation based on what access supports (max rows per table, max identifier lengths). git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@361 f203690c-595d-4dc9-a70b-905162fa7fd2 --- src/changes/changes.xml | 4 +++ .../healthmarketscience/jackcess/Column.java | 6 ++-- .../jackcess/Database.java | 28 ++++++++++++++++- .../jackcess/JetFormat.java | 30 ++++++++++++++++++- 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 3d2dcf9..9f164e2 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -14,6 +14,10 @@ Better column type translation for very large MEMO/OLE types in the Database.copyTable logic. + + Add some more limit checking into table creation based on what access + supports (max rows per table, max identifier lengths). + diff --git a/src/java/com/healthmarketscience/jackcess/Column.java b/src/java/com/healthmarketscience/jackcess/Column.java index 5987ae3..76012ef 100644 --- a/src/java/com/healthmarketscience/jackcess/Column.java +++ b/src/java/com/healthmarketscience/jackcess/Column.java @@ -321,9 +321,9 @@ public class Column implements Comparable { if(getType() == null) { throw new IllegalArgumentException("must have type"); } - if((getName() == null) || (getName().trim().length() == 0)) { - throw new IllegalArgumentException("must have valid name"); - } + Database.validateIdentifierName(getName(), format.MAX_COLUMN_NAME_LENGTH, + "column"); + if(isVariableLength() != getType().isVariableLength()) { throw new IllegalArgumentException("invalid variable length setting"); } diff --git a/src/java/com/healthmarketscience/jackcess/Database.java b/src/java/com/healthmarketscience/jackcess/Database.java index 189c9cc..c45d998 100644 --- a/src/java/com/healthmarketscience/jackcess/Database.java +++ b/src/java/com/healthmarketscience/jackcess/Database.java @@ -489,15 +489,23 @@ public class Database public void createTable(String name, List columns) throws IOException { + validateIdentifierName(name, _format.MAX_TABLE_NAME_LENGTH, "table"); + if(getTable(name) != null) { throw new IllegalArgumentException( "Cannot create table with name of existing table"); } + if(columns.isEmpty()) { throw new IllegalArgumentException( "Cannot create table with no columns"); } - + if(columns.size() > _format.MAX_COLUMNS_PER_TABLE) { + throw new IllegalArgumentException( + "Cannot create table with more than " + + _format.MAX_COLUMNS_PER_TABLE + " columns"); + } + Set colNames = new HashSet(); // next, validate the column definitions for(Column column : columns) { @@ -945,6 +953,24 @@ public class Database 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() { diff --git a/src/java/com/healthmarketscience/jackcess/JetFormat.java b/src/java/com/healthmarketscience/jackcess/JetFormat.java index d0900f1..38b4bc5 100644 --- a/src/java/com/healthmarketscience/jackcess/JetFormat.java +++ b/src/java/com/healthmarketscience/jackcess/JetFormat.java @@ -123,6 +123,11 @@ public abstract class JetFormat { public final int SIZE_INDEX_ENTRY_MASK; public final int USAGE_MAP_TABLE_BYTE_LENGTH; + + public final int MAX_COLUMNS_PER_TABLE; + public final int MAX_TABLE_NAME_LENGTH; + public final int MAX_COLUMN_NAME_LENGTH; + public final int MAX_INDEX_NAME_LENGTH; public final Charset CHARSET; @@ -210,6 +215,12 @@ public abstract class JetFormat { SIZE_INDEX_ENTRY_MASK = defineSizeIndexEntryMask(); USAGE_MAP_TABLE_BYTE_LENGTH = defineUsageMapTableByteLength(); + + MAX_COLUMNS_PER_TABLE = defineMaxColumnsPerTable(); + MAX_TABLE_NAME_LENGTH = defineMaxTableNameLength(); + MAX_COLUMN_NAME_LENGTH = defineMaxColumnNameLength(); + MAX_INDEX_NAME_LENGTH = defineMaxIndexNameLength(); + CHARSET = defineCharset(); } @@ -276,7 +287,12 @@ public abstract class JetFormat { protected abstract int defineSizeIndexEntryMask(); protected abstract int defineUsageMapTableByteLength(); - + + protected abstract int defineMaxColumnsPerTable(); + protected abstract int defineMaxTableNameLength(); + protected abstract int defineMaxColumnNameLength(); + protected abstract int defineMaxIndexNameLength(); + protected abstract Charset defineCharset(); @Override @@ -406,6 +422,18 @@ public abstract class JetFormat { @Override protected int defineUsageMapTableByteLength() { return 64; } + @Override + protected int defineMaxColumnsPerTable() { return 255; } + + @Override + protected int defineMaxTableNameLength() { return 64; } + + @Override + protected int defineMaxColumnNameLength() { return 64; } + + @Override + protected int defineMaxIndexNameLength() { return 64; } + @Override protected Charset defineCharset() { return Charset.forName("UTF-16LE"); } } -- 2.39.5