Browse Source

updates

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/mutateops@1006 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-2.1.5
James Ahlborn 7 years ago
parent
commit
75b8acd8a2

+ 3
- 3
src/main/java/com/healthmarketscience/jackcess/ColumnBuilder.java View File

@@ -384,12 +384,12 @@ public class ColumnBuilder {
* @usage _advanced_method_
*/
public void validate(JetFormat format) {
if(getType() == null) {
throw new IllegalArgumentException(withErrorContext("must have type"));
}
DatabaseImpl.validateIdentifierName(
getName(), format.MAX_COLUMN_NAME_LENGTH, "column");

if(getType() == null) {
throw new IllegalArgumentException(withErrorContext("must have type"));
}
if(getType().isUnsupported()) {
throw new IllegalArgumentException(withErrorContext(
"Cannot create column with unsupported type " + getType()));

+ 71
- 12
src/main/java/com/healthmarketscience/jackcess/RelationshipBuilder.java View File

@@ -17,45 +17,91 @@ limitations under the License.
package com.healthmarketscience.jackcess;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.healthmarketscience.jackcess.impl.DatabaseImpl;
import com.healthmarketscience.jackcess.impl.RelationshipCreator;
import com.healthmarketscience.jackcess.impl.RelationshipImpl;

/**
* Builder style class for constructing a {@link Relationship}, and,
* optionally, the associated backing foreign key (if referential integrity
* enforcement is enabled).
*
* @author James Ahlborn
*/
public class RelationshipBuilder
{
private static final int JOIN_FLAGS =
RelationshipImpl.LEFT_OUTER_JOIN_FLAG |
RelationshipImpl.RIGHT_OUTER_JOIN_FLAG;

/** relationship flags (default to "don't enforce") */
private int _flags = RelationshipImpl.NO_REFERENTIAL_INTEGRITY_FLAG;
private String _toTable;
private String _fromTable;
private List<String> _toCols = new ArrayList<String>();
private List<String> _fromCols = new ArrayList<String>();

// - primary table must have unique index
// - primary table index name ".rC", ".rD"...
// - secondary index name "<PTable><STable>"
// - add <name>1, <name>2 after names to make unique (index names and
// relationship names)

public RelationshipBuilder()
public RelationshipBuilder(String toTable, String fromTable)
{
_toTable = toTable;
_fromTable = fromTable;
}

/**
* Adds a pair of columns to the relationship.
*/
public RelationshipBuilder addColumns(String toCol, String fromCol) {
_toCols.add(toCol);
_fromCols.add(fromCol);
return this;
}

/**
* Enables referential integrity enforcement for this relationship.
*
* Note, this requires the "to" table to have an existing unique index on
* the relevant columns.
*/
public RelationshipBuilder setReferentialIntegrity() {
return clearFlag(RelationshipImpl.NO_REFERENTIAL_INTEGRITY_FLAG);
}

/**
* Enables deletes to be cascaded from the "to" table to the "from" table.
*
* Note, this requires referential integrity to be enforced.
*/
public RelationshipBuilder setCascadeDeletes() {
return setFlag(RelationshipImpl.CASCADE_DELETES_FLAG);
}
/**
* Enables updates to be cascaded from the "to" table to the "from" table.
*
* Note, this requires referential integrity to be enforced.
*/
public RelationshipBuilder setCascadeUpdates() {
return setFlag(RelationshipImpl.CASCADE_UPDATES_FLAG);
}

/**
* Enables deletes in the "to" table to be cascaded as "null" to the "from"
* table.
*
* Note, this requires referential integrity to be enforced.
*/
public RelationshipBuilder setCascadeNullOnDelete() {
return setFlag(RelationshipImpl.CASCADE_NULL_FLAG);
}

/**
* Sets the preferred join type for this relationship.
*/
public RelationshipBuilder setJoinType(Relationship.JoinType joinType) {
clearFlag(JOIN_FLAGS);
switch(joinType) {
case INNER:
// nothing to do
@@ -80,6 +126,22 @@ public class RelationshipBuilder
return _flags;
}

public String getToTable() {
return _toTable;
}

public String getFromTable() {
return _fromTable;
}

public List<String> getToColumns() {
return _toCols;
}
public List<String> getFromColumns() {
return _fromCols;
}
/**
* Creates a new Relationship in the given Database with the currently
* configured attributes.
@@ -87,10 +149,7 @@ public class RelationshipBuilder
public Relationship toRelationship(Database db)
throws IOException
{

// FIXME writeme
return null;
return new RelationshipCreator((DatabaseImpl)db).createRelationship(this);
}

private RelationshipBuilder setFlag(int flagMask) {

+ 70
- 13
src/main/java/com/healthmarketscience/jackcess/impl/RelationshipCreator.java View File

@@ -17,6 +17,7 @@ limitations under the License.
package com.healthmarketscience.jackcess.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@@ -29,12 +30,23 @@ import com.healthmarketscience.jackcess.RelationshipBuilder;
*/
public class RelationshipCreator extends DBMutator
{
private final static int CASCADE_FLAGS =
RelationshipImpl.CASCADE_DELETES_FLAG |
RelationshipImpl.CASCADE_UPDATES_FLAG |
RelationshipImpl.CASCADE_NULL_FLAG;
private TableImpl _primaryTable;
private TableImpl _secondaryTable;
private RelationshipBuilder _relationship;
private List<ColumnImpl> _primaryCols;
private List<ColumnImpl> _secondaryCols;
private int _flags;
// - primary table must have unique index
// - primary table index name ".rC", ".rD"...
// - secondary index name "<PTable><STable>"
// - add <name>1, <name>2 after names to make unique (index names and
// relationship names)

public RelationshipCreator(DatabaseImpl database)
{
@@ -66,7 +78,7 @@ public class RelationshipCreator extends DBMutator
throws IOException
{
_relationship = relationship;
validate();

getPageChannel().startExclusiveWrite();
@@ -85,22 +97,26 @@ public class RelationshipCreator extends DBMutator

private void validate() throws IOException {

_primaryTable = getDatabase().getTable(_relationship.getToTable());
_secondaryTable = getDatabase().getTable(_relationship.getToTable());
if((_primaryTable == null) || (_secondaryTable == null)) {
throw new IllegalArgumentException(
"Two tables are required in relationship");
}
if(_primaryTable.getDatabase() != _secondaryTable.getDatabase()) {
throw new IllegalArgumentException("Tables are not from same database");
throw new IllegalArgumentException(withErrorContext(
"Two valid tables are required in relationship"));
}

_primaryCols = getColumns(_primaryTable, _relationship.getToColumns());
_secondaryCols = getColumns(_secondaryTable, _relationship.getFromColumns());
if((_primaryCols == null) || (_primaryCols.isEmpty()) ||
(_secondaryCols == null) || (_secondaryCols.isEmpty())) {
throw new IllegalArgumentException("Missing columns in relationship");
throw new IllegalArgumentException(withErrorContext(
"Missing columns in relationship"));
}

if(_primaryCols.size() != _secondaryCols.size()) {
throw new IllegalArgumentException(
"Must have same number of columns on each side of relationship");
throw new IllegalArgumentException(withErrorContext(
"Must have same number of columns on each side of relationship"));
}

for(int i = 0; i < _primaryCols.size(); ++i) {
@@ -108,12 +124,18 @@ public class RelationshipCreator extends DBMutator
ColumnImpl scol = _primaryCols.get(i);

if(pcol.getType() != scol.getType()) {
throw new IllegalArgumentException(
"Matched columns must have the same data type");
throw new IllegalArgumentException(withErrorContext(
"Matched columns must have the same data type"));
}
}

if(!_relationship.hasReferentialIntegrity()) {

if((_relationship.getFlags() & CASCADE_FLAGS) != 0) {
throw new IllegalArgumentException(withErrorContext(
"Cascade flags cannot be enabled if referential integrity is not enforced"));
}
return;
}

@@ -123,7 +145,8 @@ public class RelationshipCreator extends DBMutator
// - cols come from right tables, tables from right db
// - (cols can be duped in index)
// - cols have same data types
// - if enforce, require unique index on primary (auto-create?), index on secondary
// - if enforce, require unique index on primary,
// - auto-create index on secondary
// - advanced, check for enforce cycles?
// - index must be ascending

@@ -186,4 +209,38 @@ public class RelationshipCreator extends DBMutator
}
}
}

private static List<ColumnImpl> getColumns(TableImpl table, List<String> colNames) {
List<ColumnImpl> cols = new ArrayList<ColumnImpl>();
for(String colName : colNames) {
cols.add(table.getColumn(colName));
}
return cols;
}

private static String getTableErrorContext(
TableImpl table, List<ColumnImpl> cols,
String tableName, List<String> colNames) {
if(table != null) {
tableName = table.getName();
}
if(cols != null) {
colNames = new ArrayList<String>();
for(ColumnImpl col : cols) {
colNames.add(col.getName());
}
}

return CustomToStringStyle.valueBuilder(tableName)
.append(null, cols)
.toString();
}
private String withErrorContext(String msg) {
return msg + "(Rel=" +
getTableErrorContext(_primaryTable, _primaryCols, _relationship.getToTable(),
_relationship.getToColumns()) + " <- " +
getTableErrorContext(_secondaryTable, _secondaryCols, _relationship.getFromTable(),
_relationship.getFromColumns()) + ")";
}
}

+ 11
- 7
src/main/java/com/healthmarketscience/jackcess/impl/TableCreator.java View File

@@ -104,7 +104,8 @@ public class TableCreator extends TableMutator
}
}
}
throw new IllegalStateException("could not find state for index");
throw new IllegalStateException(withErrorContext(
"could not find state for index"));
}

public List<IndexDataState> getIndexDataStates() {
@@ -251,13 +252,13 @@ public class TableCreator extends TableMutator
getDatabase().validateNewTableName(_name);
if((_columns == null) || _columns.isEmpty()) {
throw new IllegalArgumentException(
"Cannot create table with no columns");
throw new IllegalArgumentException(withErrorContext(
"Cannot create table with no columns"));
}
if(_columns.size() > getFormat().MAX_COLUMNS_PER_TABLE) {
throw new IllegalArgumentException(
throw new IllegalArgumentException(withErrorContext(
"Cannot create table with more than " +
getFormat().MAX_COLUMNS_PER_TABLE + " columns");
getFormat().MAX_COLUMNS_PER_TABLE + " columns"));
}
Set<String> colNames = new HashSet<String>();
@@ -278,9 +279,9 @@ public class TableCreator extends TableMutator
if(hasIndexes()) {

if(_indexes.size() > getFormat().MAX_INDEXES_PER_TABLE) {
throw new IllegalArgumentException(
throw new IllegalArgumentException(withErrorContext(
"Cannot create table with more than " +
getFormat().MAX_INDEXES_PER_TABLE + " indexes");
getFormat().MAX_INDEXES_PER_TABLE + " indexes"));
}

// now, validate the indexes
@@ -332,4 +333,7 @@ public class TableCreator extends TableMutator
(col1.getFlags() == col2.getFlags()));
}

private String withErrorContext(String msg) {
return msg + "(Table=" + getName() + ")";
}
}

+ 18
- 6
src/main/java/com/healthmarketscience/jackcess/impl/TableUpdater.java View File

@@ -173,12 +173,13 @@ public class TableUpdater extends TableMutator
private void validateAddColumn() {

if(_column == null) {
throw new IllegalArgumentException("Cannot add column with no column");
throw new IllegalArgumentException(withErrorContext(
"Cannot add column with no column"));
}
if((_table.getColumnCount() + 1) > getFormat().MAX_COLUMNS_PER_TABLE) {
throw new IllegalArgumentException(
throw new IllegalArgumentException(withErrorContext(
"Cannot add column to table with " +
getFormat().MAX_COLUMNS_PER_TABLE + " columns");
getFormat().MAX_COLUMNS_PER_TABLE + " columns"));
}
Set<String> colNames = getColumnNames();
@@ -199,12 +200,13 @@ public class TableUpdater extends TableMutator
private void validateAddIndex() {
if(_index == null) {
throw new IllegalArgumentException("Cannot add index with no index");
throw new IllegalArgumentException(withErrorContext(
"Cannot add index with no index"));
}
if((_table.getLogicalIndexCount() + 1) > getFormat().MAX_INDEXES_PER_TABLE) {
throw new IllegalArgumentException(
throw new IllegalArgumentException(withErrorContext(
"Cannot add index to table with " +
getFormat().MAX_INDEXES_PER_TABLE + " indexes");
getFormat().MAX_INDEXES_PER_TABLE + " indexes"));
}
boolean foundPk[] = new boolean[1];
@@ -291,4 +293,14 @@ public class TableUpdater extends TableMutator
((col1.getFlags() | ignoreColFlags) ==
(col2.getFlags() | ignoreColFlags)));
}

private String withErrorContext(String msg) {
String objStr = "";
if(_column != null) {
objStr = ";Column=" + _column.getName();
} else if(_index != null) {
objStr = ";Index=" + _index.getName();
}
return msg + "(Table=" + _table.getName() + objStr + ")";
}
}

Loading…
Cancel
Save