You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/07/19 23:35:07 UTC
svn commit: r423615 [26/44] - in /incubator/openjpa/trunk: ./
openjpa-jdbc-5/ openjpa-jdbc-5/src/ openjpa-jdbc-5/src/main/
openjpa-jdbc-5/src/main/java/ openjpa-jdbc-5/src/main/java/org/
openjpa-jdbc-5/src/main/java/org/apache/ openjpa-jdbc-5/src/main/...
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LazySchemaFactory.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LazySchemaFactory.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LazySchemaFactory.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LazySchemaFactory.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.SQLExceptions;
+import org.apache.openjpa.lib.conf.Configurable;
+import org.apache.openjpa.lib.conf.Configuration;
+
+/**
+ * Factory that uses database metadata to construct the system schema.
+ * The lazy schema factory only loads table data as it is requested. It
+ * does not properly support operations that require knowledge of the entire
+ * schema.
+ *
+ * @author Abe White
+ */
+public class LazySchemaFactory
+ extends SchemaGroup
+ implements SchemaFactory, Configurable {
+
+ private JDBCConfiguration _conf = null;
+ private SchemaGenerator _gen = null;
+ private Connection _conn = null;
+ private DatabaseMetaData _meta = null;
+ private boolean _indexes = false;
+ private boolean _pks = false;
+ private boolean _fks = false;
+
+ public boolean getPrimaryKeys() {
+ return _pks;
+ }
+
+ public void setPrimaryKeys(boolean pks) {
+ _pks = pks;
+ }
+
+ public boolean getForeignKeys() {
+ return _fks;
+ }
+
+ public void setForeignKeys(boolean fks) {
+ _fks = fks;
+ }
+
+ public boolean getIndexes() {
+ return _indexes;
+ }
+
+ public void setIndexes(boolean idx) {
+ _indexes = idx;
+ }
+
+ public SchemaGroup readSchema() {
+ return this;
+ }
+
+ public void storeSchema(SchemaGroup schema) {
+ // nothing to do
+ }
+
+ public Table findTable(String name) {
+ if (name == null)
+ return null;
+
+ Table table = super.findTable(name);
+ if (table != null)
+ return table;
+
+ generateSchemaObject(name, true);
+ return super.findTable(name);
+ }
+
+ public Sequence findSequence(String name) {
+ if (name == null)
+ return null;
+
+ Sequence seq = super.findSequence(name);
+ if (seq != null)
+ return seq;
+
+ generateSchemaObject(name, false);
+ return super.findSequence(name);
+ }
+
+ /**
+ * Generate the table or sequence with the given name.
+ */
+ private void generateSchemaObject(String name, boolean isTable) {
+ // if full name, split
+ String schemaName = null;
+ String objectName = name;
+
+ // look for the standard schema separator...
+ int dotIdx = name.indexOf('.');
+ // ... or the dictionary schema separator
+ if (dotIdx == -1) {
+ String sep = _conf.getDBDictionaryInstance().catalogSeparator;
+ if (!".".equals(sep))
+ dotIdx = name.indexOf(sep);
+ }
+
+ if (dotIdx != -1) {
+ schemaName = name.substring(0, dotIdx);
+ objectName = name.substring(dotIdx + 1);
+ }
+
+ // we share a single connection across all schemas, so synch
+ // on the schema group
+ synchronized (this) {
+ boolean close = false;
+ try {
+ // use the existing connection if possible; this method
+ // might be reentrant if generating the foreign keys for
+ // this table (see below) requires loading additional
+ // tables; in that case we don't want to spawn additional
+ // connections
+ if (_conn == null) {
+ _conn = _conf.getDataSource2(null).getConnection();
+ close = true;
+ _meta = _conn.getMetaData();
+ }
+
+ if (isTable) {
+ // generate the table from database metadata
+ _gen.generateTables(schemaName, objectName, _conn, _meta);
+ Table table = super.findTable(name);
+
+ if (table != null) {
+ if (_pks)
+ _gen.generatePrimaryKeys(table.getSchemaName(),
+ table.getName(), _conn, _meta);
+ if (_indexes)
+ _gen.generateIndexes(table.getSchemaName(),
+ table.getName(), _conn, _meta);
+
+ // generate foreign keys from the table; this might
+ // end up re-calling this getTable method if the foreign
+ // key links to a table that hasn't been loaded yet
+ if (_fks)
+ _gen.generateForeignKeys(table.getSchemaName(),
+ table.getName(), _conn, _meta);
+ }
+ } else
+ _gen.generateSequences(schemaName, objectName, _conn,
+ _meta);
+ } catch (SQLException se) {
+ throw SQLExceptions.getStore(se,
+ _conf.getDBDictionaryInstance());
+ } finally {
+ if (close) {
+ try {
+ _conn.close();
+ } catch (SQLException se) {
+ }
+ _conn = null;
+ }
+ }
+ }
+ }
+
+ public void setConfiguration(Configuration conf) {
+ _conf = (JDBCConfiguration) conf;
+ _gen = new SchemaGenerator(_conf);
+ _gen.setSchemaGroup(this);
+ }
+
+ public void startConfiguration() {
+ }
+
+ public void endConfiguration() {
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LazySchemaFactory.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.InvalidStateException;
+
+/**
+ * Constraint over local table columns, as opposed to a foreign key which
+ * spans tables. Column APIs can represent a full constraint or a partial
+ * constraint, aligning with {@link java.sql.DatabaseMetaData}.
+ *
+ * @author Abe White
+ */
+public abstract class LocalConstraint
+ extends Constraint {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (LocalConstraint.class);
+
+ private List _colList = null;
+ private Column[] _cols = null;
+
+ /**
+ * Default constructor.
+ */
+ public LocalConstraint() {
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name the name of the constraint, if any
+ * @param table the table of the constraint
+ */
+ public LocalConstraint(String name, Table table) {
+ super(name, table);
+ }
+
+ /**
+ * Called when the constraint is removed from its table.
+ */
+ void remove() {
+ // remove all columns
+ setColumns(null);
+ super.remove();
+ }
+
+ /**
+ * Return all the columns the constraint spans.
+ */
+ public Column[] getColumns() {
+ if (_cols == null)
+ _cols = (_colList == null) ? Schemas.EMPTY_COLUMNS
+ : (Column[]) _colList.toArray(new Column[_colList.size()]);
+ return _cols;
+ }
+
+ /**
+ * Set the columns the constraint spans.
+ */
+ public void setColumns(Column[] cols) {
+ Column[] cur = getColumns();
+ for (int i = 0; i < cur.length; i++)
+ removeColumn(cur[i]);
+
+ if (cols != null)
+ for (int i = 0; i < cols.length; i++)
+ addColumn(cols[i]);
+ }
+
+ /**
+ * Add a column to the constraint.
+ */
+ public void addColumn(Column col) {
+ if (col == null || !ObjectUtils.equals(col.getTable(), getTable()))
+ throw new InvalidStateException(_loc.get("table-mismatch",
+ col == null ? null : col.getTable(),
+ col == null ? null : getTable()));
+
+ if (_colList == null)
+ _colList = new ArrayList(3);
+ else if (_colList.contains(col))
+ return;
+
+ _colList.add(col);
+ _cols = null;
+ }
+
+ /**
+ * Remove a column from the constraint.
+ *
+ * @return true if the column was removed, false if not part of the
+ * primary key
+ */
+ public boolean removeColumn(Column col) {
+ if (col == null || _colList == null)
+ return false;
+ if (_colList.remove(col)) {
+ _cols = null;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Return true if the pk includes the given column.
+ */
+ public boolean containsColumn(Column col) {
+ if (col == null || _colList == null)
+ return false;
+ return _colList.contains(col);
+ }
+
+ /**
+ * Ref all columns in this constraint.
+ */
+ public void refColumns() {
+ Column[] cols = getColumns();
+ for (int i = 0; i < cols.length; i++)
+ cols[i].ref();
+ }
+
+ /**
+ * Deref all columns in this constraint.
+ */
+ public void derefColumns() {
+ Column[] cols = getColumns();
+ for (int i = 0; i < cols.length; i++)
+ cols[i].deref();
+ }
+
+ /**
+ * Return true if the given columns match the columns of this constraint.
+ */
+ public boolean columnsMatch(Column[] ocols) {
+ Column[] cols = getColumns();
+ if (cols.length != ocols.length)
+ return false;
+ for (int i = 0; i < ocols.length; i++)
+ if (!hasColumn(cols, ocols[i]))
+ return false;
+ return true;
+ }
+
+ /**
+ * Return whether the given column exists in the array.
+ */
+ private static boolean hasColumn(Column[] cols, Column col) {
+ for (int i = 0; i < cols.length; i++)
+ if (cols[i].getFullName().equalsIgnoreCase(col.getFullName()))
+ return true;
+ return false;
+ }
+
+ /**
+ * Return true if the columns of this constraint matches that of
+ * the given one. The constraints are not compared on name.
+ */
+ protected boolean equalsLocalConstraint(LocalConstraint lc) {
+ if (lc == this)
+ return true;
+ if (lc == null)
+ return false;
+ return columnsMatch(lc.getColumns());
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/LocalConstraint.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/NameSet.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/NameSet.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/NameSet.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/NameSet.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.openjpa.lib.util.Localizer;
+
+/**
+ * Name sets track what names have been taken, ignoring case.
+ * {@link SchemaGroup}s implement this interface for tables, indexes, and
+ * constraints; {@link Table}s implement it for their columns.
+ *
+ * @author Abe White
+ */
+public class NameSet {
+
+ private static final Localizer _loc = Localizer.forPackage(NameSet.class);
+
+ private Set _names = null;
+
+ /**
+ * Return true if the given name is in use already.
+ */
+ public boolean isNameTaken(String name) {
+ if (name == null)
+ return true;
+ return _names != null && _names.contains(name.toUpperCase());
+ }
+
+ /**
+ * Attempt to add the given name to the set.
+ *
+ * @param name the name to add
+ * @param validate if true, null or empty names will not be accepted
+ */
+ protected void addName(String name, boolean validate) {
+ if (name == null || name.length() == 0) {
+ if (validate)
+ throw new IllegalArgumentException(_loc.get("bad-name", name));
+ return;
+ }
+
+ // unfortunately, we can't check for duplicate names, because different
+ // DBs use different namespaces for components, and it would be
+ // difficult to find a scheme that fits all and is still useful
+ if (_names == null)
+ _names = new HashSet();
+ _names.add(name.toUpperCase());
+ }
+
+ /**
+ * Remove the given name from the table.
+ */
+ protected void removeName(String name) {
+ if (name != null && _names != null)
+ _names.remove(name.toUpperCase());
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/NameSet.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/PrimaryKey.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/PrimaryKey.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/PrimaryKey.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/PrimaryKey.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+/**
+ * Represents a table primary key. It can also represent a partial key,
+ * aligning with the key information available from
+ * {@link java.sql.DatabaseMetaData}.
+ *
+ * @author Abe White
+ */
+public class PrimaryKey
+ extends LocalConstraint {
+
+ private boolean _logical = false;
+
+ /**
+ * Default constructor.
+ */
+ public PrimaryKey() {
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name the name of the primary key, if any
+ * @param table the table of the primary key
+ */
+ public PrimaryKey(String name, Table table) {
+ super(name, table);
+ }
+
+ public boolean isLogical() {
+ return _logical;
+ }
+
+ public void setLogical(boolean logical) {
+ _logical = logical;
+ }
+
+ void remove() {
+ // check all foreign keys in the schema group, removing ones that
+ // reference this primary key
+ Table table = getTable();
+ if (table != null && table.getSchema() != null
+ && table.getSchema().getSchemaGroup() != null) {
+ ForeignKey[] fks = table.getSchema().getSchemaGroup().
+ findExportedForeignKeys(this);
+ for (int i = 0; i < fks.length; i++)
+ fks[i].getTable().removeForeignKey(fks[i]);
+ }
+ super.remove();
+ }
+
+ public void addColumn(Column col) {
+ super.addColumn(col);
+ col.setPrimaryKey(true);
+ if (!_logical)
+ col.setNotNull(true);
+ }
+
+ /**
+ * Return true if the structure of this primary key matches that of
+ * the given one (same table, same columns).
+ */
+ public boolean equalsPrimaryKey(PrimaryKey pk) {
+ return equalsLocalConstraint(pk);
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/PrimaryKey.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ReferenceCounter.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ReferenceCounter.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ReferenceCounter.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ReferenceCounter.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+/**
+ * Some schema components count references so that unused components
+ * can be detected.
+ *
+ * @author Abe White
+ */
+class ReferenceCounter {
+
+ private int _count = 0;
+
+ public int getRefCount() {
+ return _count;
+ }
+
+ public void ref() {
+ _count++;
+ }
+
+ public void deref() {
+ _count--;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ReferenceCounter.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Schema.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Schema.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Schema.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Schema.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Represents a database schema.
+ *
+ * @author Abe White
+ */
+public class Schema
+ implements Comparable {
+
+ private String _name = null;
+ private SchemaGroup _group = null;
+ private Map _tableMap = null;
+ private Map _seqMap = null;
+
+ // cache
+ private Table[] _tables = null;
+ private Sequence[] _seqs = null;
+
+ /**
+ * Default constructor.
+ */
+ public Schema() {
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param name the schema name, if any
+ * @param group the schema's owning group
+ */
+ public Schema(String name, SchemaGroup group) {
+ setName(name);
+ _group = group;
+ }
+
+ /**
+ * Called when the schema is removed from its group. Invalidates the
+ * schema and removes all its member tables.
+ */
+ void remove() {
+ Table[] tabs = getTables();
+ for (int i = 0; i < tabs.length; i++)
+ removeTable(tabs[i]);
+ Sequence[] seqs = getSequences();
+ for (int i = 0; i < seqs.length; i++)
+ removeSequence(seqs[i]);
+ _group = null;
+ }
+
+ /**
+ * Return the schema's group.
+ */
+ public SchemaGroup getSchemaGroup() {
+ return _group;
+ }
+
+ /**
+ * Return the name of the schema, or null if none.
+ */
+ public String getName() {
+ return _name;
+ }
+
+ /**
+ * Set the name of the schema. This method can only be used for schemas
+ * not attached to a group.
+ */
+ public void setName(String name) {
+ if (getSchemaGroup() != null)
+ throw new IllegalStateException();
+ if (name != null && name.length() == 0)
+ name = null;
+ _name = name;
+ }
+
+ /**
+ * Return the schema's tables.
+ */
+ public Table[] getTables() {
+ if (_tables == null)
+ _tables = (_tableMap == null) ? new Table[0] : (Table[])
+ _tableMap.values().toArray(new Table[_tableMap.size()]);
+ return _tables;
+ }
+
+ /**
+ * Return the table with the given name, or null if none.
+ */
+ public Table getTable(String name) {
+ if (name == null || _tableMap == null)
+ return null;
+ return (Table) _tableMap.get(name.toUpperCase());
+ }
+
+ /**
+ * Add a table to the schema.
+ */
+ public Table addTable(String name) {
+ SchemaGroup group = getSchemaGroup();
+ Table tab;
+ if (group != null) {
+ group.addName(name, true);
+ tab = group.newTable(name, this);
+ } else
+ tab = new Table(name, this);
+ if (_tableMap == null)
+ _tableMap = new TreeMap();
+ _tableMap.put(name.toUpperCase(), tab);
+ _tables = null;
+ return tab;
+ }
+
+ /**
+ * Remove the given table from the schema.
+ *
+ * @return true if the table was removed, false if not in the schema
+ */
+ public boolean removeTable(Table tab) {
+ if (tab == null || _tableMap == null)
+ return false;
+
+ Table cur = (Table) _tableMap.get(tab.getName().toUpperCase());
+ if (!cur.equals(tab))
+ return false;
+
+ _tableMap.remove(tab.getName().toUpperCase());
+ _tables = null;
+ SchemaGroup group = getSchemaGroup();
+ if (group != null)
+ group.removeName(tab.getName());
+ tab.remove();
+ return true;
+ }
+
+ /**
+ * Import a table from another schema. Note that this method does
+ * <strong>not</strong> import foreign keys, indexes, or unique constraints.
+ */
+ public Table importTable(Table table) {
+ if (table == null)
+ return null;
+
+ Table copy = addTable(table.getName());
+ Column[] cols = table.getColumns();
+ for (int i = 0; i < cols.length; i++)
+ copy.importColumn(cols[i]);
+
+ copy.importPrimaryKey(table.getPrimaryKey());
+ return copy;
+ }
+
+ /**
+ * Return the schema's sequences.
+ */
+ public Sequence[] getSequences() {
+ if (_seqs == null)
+ _seqs = (_seqMap == null) ? new Sequence[0] : (Sequence[])
+ _seqMap.values().toArray(new Sequence[_seqMap.size()]);
+ return _seqs;
+ }
+
+ /**
+ * Return the sequence with the given name, or null if none.
+ */
+ public Sequence getSequence(String name) {
+ if (name == null || _seqMap == null)
+ return null;
+ return (Sequence) _seqMap.get(name.toUpperCase());
+ }
+
+ /**
+ * Add a sequence to the schema.
+ */
+ public Sequence addSequence(String name) {
+ SchemaGroup group = getSchemaGroup();
+ Sequence seq;
+ if (group != null) {
+ group.addName(name, true);
+ seq = group.newSequence(name, this);
+ } else
+ seq = new Sequence(name, this);
+ if (_seqMap == null)
+ _seqMap = new TreeMap();
+ _seqMap.put(name.toUpperCase(), seq);
+ _seqs = null;
+ return seq;
+ }
+
+ /**
+ * Remove the given sequence from the schema.
+ *
+ * @return true if the sequence was removed, false if not in the schema
+ */
+ public boolean removeSequence(Sequence seq) {
+ if (seq == null || _seqMap == null)
+ return false;
+
+ Sequence cur = (Sequence) _seqMap.get(seq.getName().toUpperCase());
+ if (!cur.equals(seq))
+ return false;
+
+ _seqMap.remove(seq.getName().toUpperCase());
+ _seqs = null;
+ SchemaGroup group = getSchemaGroup();
+ if (group != null)
+ group.removeName(seq.getName());
+ seq.remove();
+ return true;
+ }
+
+ /**
+ * Import a sequence from another schema.
+ */
+ public Sequence importSequence(Sequence seq) {
+ if (seq == null)
+ return null;
+
+ Sequence copy = addSequence(seq.getName());
+ copy.setInitialValue(seq.getInitialValue());
+ copy.setIncrement(seq.getIncrement());
+ copy.setAllocate(seq.getAllocate());
+ return copy;
+ }
+
+ public int compareTo(Object other) {
+ String name = getName();
+ String otherName = ((Schema) other).getName();
+ if (name == null && otherName == null)
+ return 0;
+ if (name == null)
+ return 1;
+ if (otherName == null)
+ return -1;
+ return name.compareTo(otherName);
+ }
+
+ public String toString() {
+ return getName();
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Schema.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaFactory.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaFactory.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaFactory.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaFactory.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+/**
+ * Factory for {@link SchemaGroup}s. Users can plug in their own factory
+ * implementation, or rely on the ones provided. Most schema factoryies
+ * will probably implement {@link org.apache.openjpa.lib.conf.Configurable} to
+ * receive the system congiguration on construction.
+ *
+ * @author Abe White
+ */
+public interface SchemaFactory {
+
+ /**
+ * Return the schema group for the current object model and database.
+ */
+ public SchemaGroup readSchema();
+
+ /**
+ * Record the schema group after changes may have been made.
+ *
+ * @param schema the schema definition for the entire system
+ */
+ public void storeSchema(SchemaGroup schema);
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaFactory.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGenerator.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGenerator.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGenerator.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGenerator.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,943 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EventObject;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.sql.DataSource;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.Localizer;
+
+/**
+ * The SchemaGenerator creates {@link Schema}s matching the current
+ * database. All schemas are added to the current {@link SchemaGroup}.
+ * Note that tables whose name starts with "OPENJPA_" will be not be added
+ * to the database schema. This enables the creation of special tables
+ * that will never be dropped by the {@link SchemaTool}.
+ *
+ * @author Abe White
+ */
+public class SchemaGenerator {
+
+ private static final Localizer _loc = Localizer.forPackage
+ (SchemaGenerator.class);
+
+ private final DataSource _ds;
+ private final DBDictionary _dict;
+ private final Log _log;
+ private final Object[][] _allowed;
+ private boolean _indexes = true;
+ private boolean _fks = true;
+ private boolean _pks = true;
+ private boolean _seqs = true;
+ private boolean _openjpaTables = true;
+ private SchemaGroup _group = null;
+
+ private List _listeners = null;
+ private int _schemaObjects = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param conf configuration for connecting to the data store
+ */
+ public SchemaGenerator(JDBCConfiguration conf) {
+ // note: we cannot assert developer capabilities in this tool like
+ // we normally do because this class is also used at runtime
+
+ _ds = conf.getDataSource2(null);
+ _log = conf.getLog(JDBCConfiguration.LOG_SCHEMA);
+
+ // cache this now so that if the conn pool only has 1 connection we
+ // don't conflict later with the open databasemetadata connection
+ _dict = conf.getDBDictionaryInstance();
+
+ // create a table of allowed schema and tables to reflect on
+ _allowed = parseSchemasList(conf.getSchemasList());
+ }
+
+ /**
+ * Given a list of schema names and table names (where table names
+ * are always of the form schema.table, or just .table if the schema is
+ * unknown), creates a table mapping schema name to table list. Returns
+ * null if no args are given. If no tables are given for a particular
+ * schema, maps the schema name to null.
+ */
+ private static Object[][] parseSchemasList(String[] args) {
+ if (args == null || args.length == 0)
+ return null;
+
+ Map schemas = new HashMap();
+ String schema, table;
+ int dotIdx;
+ Collection tables;
+ for (int i = 0; i < args.length; i++) {
+ dotIdx = args[i].indexOf('.');
+ if (dotIdx == -1) {
+ schema = args[i];
+ table = null;
+ } else if (dotIdx == 0) {
+ schema = null;
+ table = args[i].substring(1);
+ } else {
+ schema = args[i].substring(0, dotIdx);
+ table = args[i].substring(dotIdx + 1);
+ }
+
+ // if just a schema name, map schema to null
+ if (table == null && !schemas.containsKey(schema))
+ schemas.put(schema, null);
+ else if (table != null) {
+ tables = (Collection) schemas.get(schema);
+ if (tables == null) {
+ tables = new LinkedList();
+ schemas.put(schema, tables);
+ }
+ tables.add(table);
+ }
+ }
+
+ Object[][] parsed = new Object[schemas.size()][2];
+ Map.Entry entry;
+ int idx = 0;
+ for (Iterator itr = schemas.entrySet().iterator(); itr.hasNext();) {
+ entry = (Map.Entry) itr.next();
+ tables = (Collection) entry.getValue();
+
+ parsed[idx][0] = entry.getKey();
+ if (tables != null)
+ parsed[idx][1] = tables.toArray(new String[tables.size()]);
+ idx++;
+ }
+ return parsed;
+ }
+
+ /**
+ * Return whether indexes should be generated. Defaults to true.
+ */
+ public boolean getIndexes() {
+ return _indexes;
+ }
+
+ /**
+ * Set whether indexes should be generated. Defaults to true.
+ */
+ public void setIndexes(boolean indexes) {
+ _indexes = indexes;
+ }
+
+ /**
+ * Return whether foreign keys should be generated. Defaults to true.
+ */
+ public boolean getForeignKeys() {
+ return _fks;
+ }
+
+ /**
+ * Set whether foreign keys should be generated. Defaults to true.
+ */
+ public void setForeignKeys(boolean fks) {
+ _fks = fks;
+ }
+
+ /**
+ * Return whether primary keys should be generated. Defaults to true.
+ */
+ public boolean getPrimaryKeys() {
+ return _pks;
+ }
+
+ /**
+ * Set whether primary keys should be generated. Defaults to true.
+ */
+ public void setPrimaryKeys(boolean pks) {
+ _pks = pks;
+ }
+
+ /**
+ * Return whether sequences should be generated. Defaults to true.
+ */
+ public boolean getSequences() {
+ return _seqs;
+ }
+
+ /**
+ * Set whether sequences should be generated. Defaults to true.
+ */
+ public void setSequences(boolean seqs) {
+ _seqs = seqs;
+ }
+
+ /**
+ * Whether to generate info on special tables used by OpenJPA components
+ * for bookkeeping. Defaults to true.
+ */
+ public boolean getOpenJPATables() {
+ return _openjpaTables;
+ }
+
+ /**
+ * Whether to generate info on special tables used by OpenJPA components
+ * for bookkeeping. Defaults to true.
+ */
+ public void setOpenJPATables(boolean openjpaTables) {
+ _openjpaTables = openjpaTables;
+ }
+
+ /**
+ * Return the current schema group.
+ */
+ public SchemaGroup getSchemaGroup() {
+ if (_group == null)
+ _group = new SchemaGroup();
+ return _group;
+ }
+
+ /**
+ * Set the schema group to add generated schemas to.
+ */
+ public void setSchemaGroup(SchemaGroup group) {
+ _group = group;
+ }
+
+ /**
+ * Generate all schemas set in the configuration. This method also
+ * calls {@link #generateIndexes}, {@link #generatePrimaryKeys}, and
+ * {@link #generateForeignKeys} automatically.
+ */
+ public void generateSchemas()
+ throws SQLException {
+ fireGenerationEvent(_loc.get("generating-schemas"));
+ generateSchemas(null);
+ }
+
+ /**
+ * Generate the schemas and/or tables named in the given strings.
+ * This method calls {@link #generateIndexes},
+ * {@link #generatePrimaryKeys}, and {@link #generateForeignKeys}
+ * automatically.
+ */
+ public void generateSchemas(String[] schemasAndTables)
+ throws SQLException {
+ fireGenerationEvent(_loc.get("generating-schemas"));
+
+ Object[][] schemaMap;
+ if (schemasAndTables == null || schemasAndTables.length == 0)
+ schemaMap = _allowed;
+ else
+ schemaMap = parseSchemasList(schemasAndTables);
+
+ if (schemaMap == null) {
+ generateSchema(null, null);
+
+ // estimate the number of schema objects we will need to visit
+ // in order to estimate progresss total for any listeners
+ int numTables = getTables(null).size();
+ _schemaObjects += numTables
+ + (_pks ? numTables : 0)
+ + (_indexes ? numTables : 0)
+ + (_fks ? numTables : 0);
+
+ if (_pks)
+ generatePrimaryKeys(null, null);
+ if (_indexes)
+ generateIndexes(null, null);
+ if (_fks)
+ generateForeignKeys(null, null);
+ return;
+ }
+
+ // generate all schemas and tables
+ for (int i = 0; i < schemaMap.length; i++)
+ generateSchema((String) schemaMap[i][0],
+ (String[]) schemaMap[i][1]);
+
+ // generate pks, indexes, fks
+ String schemaName;
+ String[] tableNames;
+ for (int i = 0; i < schemaMap.length; i++) {
+ schemaName = (String) schemaMap[i][0];
+ tableNames = (String[]) schemaMap[i][1];
+
+ // estimate the number of schema objects we will need to visit
+ // in order to estimate progresss total for any listeners
+ int numTables = (tableNames != null) ? tableNames.length
+ : getTables(schemaName).size();
+ _schemaObjects += numTables
+ + (_pks ? numTables : 0)
+ + (_indexes ? numTables : 0)
+ + (_fks ? numTables : 0);
+
+ if (_pks)
+ generatePrimaryKeys(schemaName, tableNames);
+ if (_indexes)
+ generateIndexes(schemaName, tableNames);
+ if (_fks)
+ generateForeignKeys(schemaName, tableNames);
+ }
+ }
+
+ /**
+ * Add a fully-constructed {@link Schema} matching the given database
+ * schema to the current group. No foreign keys are generated because
+ * some keys might span schemas. You must call
+ * {@link #generatePrimaryKeys}, {@link #generateIndexes}, and
+ * {@link #generateForeignKeys} separately.
+ *
+ * @param name the database name of the schema, or null for all schemas
+ * @param tableNames a list of tables to generate in the schema, or null
+ * to generate all tables
+ */
+ public void generateSchema(String name, String[] tableNames)
+ throws SQLException {
+ fireGenerationEvent(_loc.get("generating-schema", name));
+
+ // generate tables, including columns and primary keys
+ Connection conn = _ds.getConnection();
+ DatabaseMetaData meta = conn.getMetaData();
+ try {
+ if (tableNames == null)
+ generateTables(name, null, conn, meta);
+ else
+ for (int i = 0; i < tableNames.length; i++)
+ generateTables(name, tableNames[i], conn, meta);
+
+ if (_seqs)
+ generateSequences(name, null, conn, meta);
+ } finally {
+ // some databases require a commit after metadata to release locks
+ try {
+ conn.commit();
+ } catch (SQLException se) {
+ }
+ try {
+ conn.close();
+ } catch (SQLException se) {
+ }
+ }
+ }
+
+ /**
+ * Generate primary key information for the given schema. This method
+ * must be called in addition to {@link #generateSchema}. It should
+ * only be called after all schemas are generated. The schema name and
+ * tables array can be null to indicate that indexes should be generated
+ * for all schemas and/or tables.
+ */
+ public void generatePrimaryKeys(String schemaName, String[] tableNames)
+ throws SQLException {
+ fireGenerationEvent(_loc.get("generating-all-primaries", schemaName));
+
+ Connection conn = _ds.getConnection();
+ DatabaseMetaData meta = conn.getMetaData();
+ try {
+ if (tableNames == null)
+ generatePrimaryKeys(schemaName, null, conn, meta);
+ else
+ for (int i = 0; i < tableNames.length; i++)
+ generatePrimaryKeys(schemaName, tableNames[i], conn, meta);
+ } finally {
+ // some databases require a commit after metadata to release locks
+ try {
+ conn.commit();
+ } catch (SQLException se) {
+ }
+ try {
+ conn.close();
+ } catch (SQLException se) {
+ }
+ }
+ }
+
+ /**
+ * Generate index information for the given schema. This method
+ * must be called in addition to {@link #generateSchema}. It should
+ * only be called after all schemas are generated. The schema name and
+ * tables array can be null to indicate that indexes should be generated
+ * for all schemas and/or tables.
+ */
+ public void generateIndexes(String schemaName, String[] tableNames)
+ throws SQLException {
+ fireGenerationEvent(_loc.get("generating-all-indexes", schemaName));
+
+ Connection conn = _ds.getConnection();
+ DatabaseMetaData meta = conn.getMetaData();
+ try {
+ if (tableNames == null)
+ generateIndexes(schemaName, null, conn, meta);
+ else
+ for (int i = 0; i < tableNames.length; i++)
+ generateIndexes(schemaName, tableNames[i], conn, meta);
+ } finally {
+ // some databases require a commit after metadata to release locks
+ try {
+ conn.commit();
+ } catch (SQLException se) {
+ }
+ try {
+ conn.close();
+ } catch (SQLException se) {
+ }
+ }
+ }
+
+ /**
+ * Generate foreign key information for the given schema. This method
+ * must be called in addition to {@link #generateSchema}. It should
+ * only be called after all schemas are generated. The schema name and
+ * tables array can be null to indicate that indexes should be generated
+ * for all schemas and/or tables.
+ */
+ public void generateForeignKeys(String schemaName, String[] tableNames)
+ throws SQLException {
+ fireGenerationEvent(_loc.get("generating-all-foreigns", schemaName));
+
+ Connection conn = _ds.getConnection();
+ DatabaseMetaData meta = conn.getMetaData();
+ try {
+ if (tableNames == null)
+ generateForeignKeys(schemaName, null, conn, meta);
+ else
+ for (int i = 0; i < tableNames.length; i++)
+ generateForeignKeys(schemaName, tableNames[i], conn, meta);
+ } finally {
+ // some databases require a commit after metadata to release locks
+ try {
+ conn.commit();
+ } catch (SQLException se) {
+ }
+ try {
+ conn.close();
+ } catch (SQLException se) {
+ }
+ }
+ }
+
+ /**
+ * Adds all tables matching the given name pattern to the schema.
+ */
+ public void generateTables(String schemaName, String tableName,
+ Connection conn, DatabaseMetaData meta)
+ throws SQLException {
+ fireGenerationEvent(_loc.get("generating-columns", schemaName,
+ tableName));
+ if (_log.isInfoEnabled())
+ _log.info(_loc.get("gen-tables", schemaName, tableName));
+
+ Column[] cols = _dict.getColumns(meta, conn.getCatalog(), schemaName,
+ tableName, null, conn);
+
+ // when we want to get all the columns for all tables, we need to build
+ // a list of tables to verify because some databases (e.g., Postgres)
+ // will include indexes in the list of columns, and there is no way to
+ // distinguish the indexes from proper columns
+ Set tableNames = null;
+ if (tableName == null || "%".equals(tableName)) {
+ Table[] tables = _dict.getTables(meta, conn.getCatalog(),
+ schemaName, tableName, conn);
+ tableNames = new HashSet();
+ for (int i = 0; tables != null && i < tables.length; i++) {
+ if (cols == null)
+ tableNames.add(tables[i].getName());
+ else
+ tableNames.add(tables[i].getName().toUpperCase());
+ }
+ }
+
+ // if database can't handle null table name, recurse on each known name
+ if (cols == null && tableName == null) {
+ for (Iterator itr = tableNames.iterator(); itr.hasNext();)
+ generateTables(schemaName, (String) itr.next(), conn, meta);
+ return;
+ }
+
+ SchemaGroup group = getSchemaGroup();
+ Schema schema;
+ Table table;
+ String tableSchema;
+ for (int i = 0; cols != null && i < cols.length; i++) {
+ tableName = cols[i].getTableName();
+ tableSchema = cols[i].getSchemaName();
+ if (tableSchema != null && tableSchema.length() == 0)
+ tableSchema = null;
+
+ // ignore special tables
+ if (!_openjpaTables &&
+ (tableName.toUpperCase().startsWith("OPENJPA_")
+ || tableName.toUpperCase().startsWith("JDO_"))) // legacy
+ continue;
+ if (_dict.isSystemTable(tableName, tableSchema, schemaName != null))
+ continue;
+
+ // ignore tables not in list, or not allowed by schemas property
+ if (tableNames != null
+ && !tableNames.contains(tableName.toUpperCase()))
+ continue;
+ if (!isAllowedTable(tableSchema, tableName))
+ continue;
+
+ schema = group.getSchema(tableSchema);
+ if (schema == null)
+ schema = group.addSchema(tableSchema);
+
+ table = schema.getTable(tableName);
+ if (table == null) {
+ table = schema.addTable(tableName);
+ if (_log.isTraceEnabled())
+ _log.trace(_loc.get("col-table", table));
+ }
+
+ if (_log.isTraceEnabled())
+ _log.trace(_loc.get("gen-column", cols[i].getName(), table));
+
+ if (table.getColumn(cols[i].getName()) == null)
+ table.importColumn(cols[i]);
+ }
+ }
+
+ /**
+ * Return whether the given table is allowed by the user's schema list.
+ */
+ private boolean isAllowedTable(String schema, String table) {
+ if (_allowed == null)
+ return true;
+
+ // do case-insensitive comparison on allowed table and schema names
+ String[] tables;
+ String[] anySchemaTables = null;
+ for (int i = 0; i < _allowed.length; i++) {
+ if (_allowed[i][0] == null) {
+ anySchemaTables = (String[]) _allowed[i][1];
+ if (schema == null)
+ break;
+ continue;
+ }
+ if (!StringUtils.equalsIgnoreCase(schema, (String) _allowed[i][0]))
+ continue;
+
+ if (table == null)
+ return true;
+ tables = (String[]) _allowed[i][1];
+ if (tables == null)
+ return true;
+ for (int j = 0; j < tables.length; j++)
+ if (StringUtils.equalsIgnoreCase(table, tables[j]))
+ return true;
+ }
+
+ if (anySchemaTables != null) {
+ if (table == null)
+ return true;
+ for (int i = 0; i < anySchemaTables.length; i++)
+ if (StringUtils.equalsIgnoreCase(table, anySchemaTables[i]))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Generates table primary keys.
+ */
+ public void generatePrimaryKeys(String schemaName, String tableName,
+ Connection conn, DatabaseMetaData meta)
+ throws SQLException {
+ fireGenerationEvent(_loc.get("generating-primary",
+ schemaName, tableName));
+ if (_log.isTraceEnabled())
+ _log.trace(_loc.get("gen-pks", schemaName, tableName));
+
+ // if looking for a non-existant table, just return
+ SchemaGroup group = getSchemaGroup();
+ if (tableName != null && group.findTable(tableName) == null)
+ return;
+
+ // if the database can't use a table name wildcard, recurse on each
+ // concrete table in the requested schema(s)
+ PrimaryKey[] pks = _dict.getPrimaryKeys(meta, conn.getCatalog(),
+ schemaName, tableName, conn);
+ Table table;
+ if (pks == null && tableName == null) {
+ Collection tables = getTables(schemaName);
+ for (Iterator itr = tables.iterator(); itr.hasNext();) {
+ table = (Table) itr.next();
+ generatePrimaryKeys(table.getSchemaName(),
+ table.getName(), conn, meta);
+ }
+ return;
+ }
+
+ Schema schema;
+ PrimaryKey pk;
+ String name;
+ String colName;
+ for (int i = 0; pks != null && i < pks.length; i++) {
+ schemaName = pks[i].getSchemaName();
+ if (schemaName != null && schemaName.length() == 0)
+ schemaName = null;
+ schema = group.getSchema(schemaName);
+ if (schema == null)
+ continue;
+ table = schema.getTable(pks[i].getTableName());
+ if (table == null)
+ continue;
+
+ colName = pks[i].getColumnName();
+ name = pks[i].getName();
+ if (_log.isTraceEnabled())
+ _log.trace(_loc.get("gen-pk", name, table, colName));
+
+ pk = table.getPrimaryKey();
+ if (pk == null)
+ pk = table.addPrimaryKey(name);
+ pk.addColumn(table.getColumn(colName));
+ }
+ }
+
+ /**
+ * Generates table indexes.
+ */
+ public void generateIndexes(String schemaName, String tableName,
+ Connection conn, DatabaseMetaData meta)
+ throws SQLException {
+ fireGenerationEvent(_loc.get("generating-indexes",
+ schemaName, tableName));
+ if (_log.isTraceEnabled())
+ _log.trace(_loc.get("gen-indexes", schemaName, tableName));
+
+ // if looking for a non-existant table, just return
+ SchemaGroup group = getSchemaGroup();
+ if (tableName != null && group.findTable(tableName) == null)
+ return;
+
+ // if the database can't use a table name wildcard, recurse on each
+ // concrete table in the requested schema(s)
+ Index[] idxs = _dict.getIndexInfo(meta, conn.getCatalog(),
+ schemaName, tableName, false, true, conn);
+ Table table;
+ if (idxs == null && tableName == null) {
+ Collection tables = getTables(schemaName);
+ for (Iterator itr = tables.iterator(); itr.hasNext();) {
+ table = (Table) itr.next();
+ generateIndexes(table.getSchemaName(),
+ table.getName(), conn, meta);
+ }
+ return;
+ }
+
+ Schema schema;
+ Index idx;
+ String name;
+ String colName;
+ String pkName;
+ for (int i = 0; idxs != null && i < idxs.length; i++) {
+ schemaName = idxs[i].getSchemaName();
+ if (schemaName != null && schemaName.length() == 0)
+ schemaName = null;
+ schema = group.getSchema(schemaName);
+ if (schema == null)
+ continue;
+ table = schema.getTable(idxs[i].getTableName());
+ if (table == null)
+ continue;
+
+ if (table.getPrimaryKey() != null)
+ pkName = table.getPrimaryKey().getName();
+ else
+ pkName = null;
+
+ // statistics don't have names; skip them
+ name = idxs[i].getName();
+ if (name == null || name.length() == 0
+ || (pkName != null && name.equalsIgnoreCase(pkName))
+ || _dict.isSystemIndex(name, table))
+ continue;
+
+ colName = idxs[i].getColumnName();
+ if (table.getColumn(colName) == null)
+ continue;
+
+ if (_log.isTraceEnabled())
+ _log.trace(_loc.get("gen-index", name, table, colName));
+
+ // same index may have multiple rows for multiple cols
+ idx = table.getIndex(name);
+ if (idx == null) {
+ idx = table.addIndex(name);
+ idx.setUnique(idxs[i].isUnique());
+ }
+ idx.addColumn(table.getColumn(colName));
+ }
+ }
+
+ /**
+ * Generates table foreign keys.
+ */
+ public void generateForeignKeys(String schemaName, String tableName,
+ Connection conn, DatabaseMetaData meta)
+ throws SQLException {
+ fireGenerationEvent(_loc.get("generating-foreign",
+ schemaName, tableName));
+ if (_log.isTraceEnabled())
+ _log.trace(_loc.get("gen-fks", schemaName, tableName));
+
+ // if looking for a non-existant table, just return
+ SchemaGroup group = getSchemaGroup();
+ if (tableName != null && group.findTable(tableName) == null)
+ return;
+
+ // if the database can't use a table name wildcard, recurse on each
+ // concrete table in the requested schema(s)
+ ForeignKey[] fks = _dict.getImportedKeys(meta, conn.getCatalog(),
+ schemaName, tableName, conn);
+ Table table;
+ if (fks == null && tableName == null) {
+ Collection tables = getTables(schemaName);
+ for (Iterator itr = tables.iterator(); itr.hasNext();) {
+ table = (Table) itr.next();
+ generateForeignKeys(table.getSchemaName(),
+ table.getName(), conn, meta);
+ }
+ return;
+ }
+
+ Schema schema;
+ Table pkTable;
+ ForeignKey fk;
+ String name;
+ String pkSchemaName;
+ String pkTableName;
+ String pkColName;
+ String fkColName;
+ int seq;
+ boolean seqWas0 = false; // some drivers incorrectly start at 0
+ Collection invalids = null;
+ for (int i = 0; fks != null && i < fks.length; i++) {
+ schemaName = fks[i].getSchemaName();
+ if (schemaName != null && schemaName.length() == 0)
+ schemaName = null;
+ schema = group.getSchema(schemaName);
+ if (schema == null)
+ continue;
+ table = schema.getTable(fks[i].getTableName());
+ if (table == null)
+ continue;
+
+ name = fks[i].getName();
+ fkColName = fks[i].getColumnName();
+ pkColName = fks[i].getPrimaryKeyColumnName();
+ seq = fks[i].getKeySequence();
+ if (seq == 0)
+ seqWas0 = true;
+ if (seqWas0)
+ seq++;
+
+ // find pk table
+ pkSchemaName = fks[i].getPrimaryKeySchemaName();
+ pkTableName = fks[i].getPrimaryKeyTableName();
+ if (_log.isTraceEnabled())
+ _log.trace(_loc.get("gen-fk", new Object[]{ name, table,
+ fkColName, pkTableName, pkColName, seq + "" }));
+
+ if (pkSchemaName != null && pkSchemaName.length() > 0)
+ pkTableName = pkSchemaName + "." + pkTableName;
+ pkTable = group.findTable(pkTableName);
+ if (pkTable == null)
+ throw new SQLException(_loc.get("gen-nofktable",
+ table, pkTableName));
+
+ // this sucks, because it is *not* guaranteed to work;
+ // the fk resultset is ordered by primary key table, then
+ // sequence number within the foreign key (some drivers don't
+ // use sequence numbers correctly either); since fk names
+ // are allowed to be null, all this adds up to the fact
+ // that there is absolutely no way to distinguish between
+ // multiple multi-column fks to the same table; we're going
+ // to rely on fk name here and hope it works
+ fk = table.getForeignKey(name);
+
+ // start a new fk?
+ if (seq == 1 || fk == null) {
+ fk = table.addForeignKey(name);
+ fk.setDeferred(fks[i].isDeferred());
+ fk.setDeleteAction(fks[i].getDeleteAction());
+ }
+
+ if (invalids == null || !invalids.contains(fk)) {
+ try {
+ fk.join(table.getColumn(fkColName),
+ pkTable.getColumn(pkColName));
+ } catch (IllegalArgumentException iae) {
+ if (_log.isWarnEnabled())
+ _log.warn(_loc.get("bad-join", iae.toString()));
+ if (invalids == null)
+ invalids = new HashSet();
+ invalids.add(fk);
+ }
+ }
+ }
+
+ // remove invalid fks
+ if (invalids != null) {
+ for (Iterator itr = invalids.iterator(); itr.hasNext();) {
+ fk = (ForeignKey) itr.next();
+ fk.getTable().removeForeignKey(fk);
+ }
+ }
+ }
+
+ /**
+ * Adds all sequences matching the given name pattern to the schema.
+ */
+ public void generateSequences(String schemaName, String sequenceName,
+ Connection conn, DatabaseMetaData meta)
+ throws SQLException {
+ fireGenerationEvent(_loc.get("generating-sequences", schemaName));
+ if (_log.isInfoEnabled())
+ _log.info(_loc.get("gen-seqs", schemaName, sequenceName));
+
+ Sequence[] seqs = _dict.getSequences(meta, conn.getCatalog(),
+ schemaName, sequenceName, conn);
+
+ SchemaGroup group = getSchemaGroup();
+ Schema schema;
+ String sequenceSchema;
+ for (int i = 0; seqs != null && i < seqs.length; i++) {
+ sequenceName = seqs[i].getName();
+ sequenceSchema = seqs[i].getSchemaName();
+ if (sequenceSchema != null && sequenceSchema.length() == 0)
+ sequenceSchema = null;
+
+ // ignore special tables
+ if (!_openjpaTables &&
+ (sequenceName.toUpperCase().startsWith("OPENJPA_")
+ || sequenceName.toUpperCase().startsWith("JDO_"))) // legacy
+ continue;
+ if (_dict.isSystemSequence(sequenceName, sequenceSchema,
+ schemaName != null))
+ continue;
+ if (!isAllowedTable(sequenceSchema, null))
+ continue;
+
+ schema = group.getSchema(sequenceSchema);
+ if (schema == null)
+ schema = group.addSchema(sequenceSchema);
+ if (schema.getSequence(sequenceName) == null)
+ schema.addSequence(sequenceName);
+ }
+ }
+
+ /**
+ * Notify any listeners that a schema object was generated. Returns
+ * true if generation should continue.
+ */
+ private void fireGenerationEvent(Object schemaObject)
+ throws SQLException {
+ if (schemaObject == null)
+ return;
+ if (_listeners == null || _listeners.size() == 0)
+ return;
+
+ Event e = new Event(schemaObject, _schemaObjects);
+ for (Iterator i = _listeners.iterator(); i.hasNext();) {
+ Listener l = (Listener) i.next();
+ if (!l.schemaObjectGenerated(e))
+ throw new SQLException(_loc.get("refresh-cancelled"));
+ }
+ }
+
+ /**
+ * Adds a listener for schema generation events.
+ *
+ * @param l the listener to add
+ */
+ public void addListener(Listener l) {
+ if (_listeners == null)
+ _listeners = new LinkedList();
+ _listeners.add(l);
+ }
+
+ /**
+ * Removes a schema generation listener for schema events.
+ *
+ * @param l the listener to remove
+ * @return true if it was successfully removed
+ */
+ public boolean removeListener(Listener l) {
+ return _listeners != null && _listeners.remove(l);
+ }
+
+ /**
+ * Return all tables for the given schema name, or all tables in
+ * the schema group if null is given.
+ */
+ private Collection getTables(String schemaName) {
+ SchemaGroup group = getSchemaGroup();
+ if (schemaName != null) {
+ Schema schema = group.getSchema(schemaName);
+ if (schema == null)
+ return Collections.EMPTY_LIST;
+ return Arrays.asList(schema.getTables());
+ }
+
+ Schema[] schemas = group.getSchemas();
+ Collection tables = new LinkedList();
+ for (int i = 0; i < schemas.length; i++)
+ tables.addAll(Arrays.asList(schemas[i].getTables()));
+ return tables;
+ }
+
+ /**
+ * A listener for a potentially lengthy schema generation process.
+ */
+ public static interface Listener {
+
+ boolean schemaObjectGenerated(Event e);
+ }
+
+ /**
+ * An event corresponding to the generation of a schema object.
+ */
+ public class Event
+ extends EventObject {
+
+ private final int _total;
+
+ public Event(Object ob, int total) {
+ super(ob);
+ _total = total;
+ }
+
+ public int getTotal() {
+ return _total;
+ }
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGenerator.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGroup.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGroup.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGroup.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGroup.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,401 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+/**
+ * Represents a grouping of schemas used in a database.
+ *
+ * @author Abe White
+ */
+public class SchemaGroup
+ extends NameSet
+ implements Cloneable {
+
+ private Map _schemaMap = null;
+
+ // cache
+ private Schema[] _schemas = null;
+
+ /**
+ * Return all schemas.
+ */
+ public Schema[] getSchemas() {
+ if (_schemas == null)
+ _schemas = (_schemaMap == null) ? new Schema[0] : (Schema[])
+ _schemaMap.values().toArray(new Schema[_schemaMap.size()]);
+ return _schemas;
+ }
+
+ /**
+ * Return the schema with the given name, or null if none.
+ */
+ public Schema getSchema(String name) {
+ if (_schemaMap == null)
+ return null;
+ if (name != null)
+ name = name.toUpperCase();
+ return (Schema) _schemaMap.get(name);
+ }
+
+ /**
+ * Add a schema to the group.
+ */
+ public Schema addSchema() {
+ return addSchema(null);
+ }
+
+ /**
+ * Add a schema to the group.
+ */
+ public Schema addSchema(String name) {
+ addName(name, false);
+ Schema schema = newSchema(name);
+ if (name != null)
+ name = name.toUpperCase();
+ if (_schemaMap == null)
+ _schemaMap = new HashMap();
+ _schemaMap.put(name, schema);
+ _schemas = null;
+ return schema;
+ }
+
+ /**
+ * Remove the given schema from the group.
+ *
+ * @return true if the schema was removed, false if not in the group
+ */
+ public boolean removeSchema(Schema schema) {
+ if (schema == null)
+ return false;
+
+ String name = schema.getName();
+ if (name != null)
+ name = name.toUpperCase();
+ Schema rem = (Schema) _schemaMap.get(name);
+ if (schema.equals(rem)) {
+ _schemaMap.remove(name);
+ removeName(schema.getName());
+ _schemas = null;
+ schema.remove();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Import a schema from another group. Foreign keys are not imported.
+ */
+ public Schema importSchema(Schema schema) {
+ if (schema == null)
+ return null;
+
+ Schema copy = addSchema(schema.getName());
+ Sequence[] seqs = schema.getSequences();
+ for (int i = 0; i < seqs.length; i++)
+ copy.importSequence(seqs[i]);
+
+ Table[] tables = schema.getTables();
+ Index[] idxs;
+ Unique[] unqs;
+ Table tab;
+ for (int i = 0; i < tables.length; i++) {
+ tab = copy.importTable(tables[i]);
+ idxs = tables[i].getIndexes();
+ for (int j = 0; j < idxs.length; j++)
+ tab.importIndex(idxs[j]);
+ unqs = tables[i].getUniques();
+ for (int j = 0; j < unqs.length; j++)
+ tab.importUnique(unqs[j]);
+ }
+ return copy;
+ }
+
+ /**
+ * Return true if the given table is known to exist. While
+ * {@link #findTable} may exhibit dynamic behavior in some schema group
+ * implementations, this method only returns true if the table has been
+ * added to this group or is known to exist in the database.
+ */
+ public boolean isKnownTable(Table table) {
+ return findTable(table) != null;
+ }
+
+ /**
+ * Return true if the given table is known to exist. While
+ * {@link #findTable} may exhibit dynamic behavior in some schema group
+ * implementations, this method only returns true if the table has been
+ * added to this group or is known to exist in the database.
+ */
+ public boolean isKnownTable(String name) {
+ return findTable(name) != null;
+ }
+
+ /**
+ * Find the equivalent of the given table in this schema group. The
+ * given table that may have come from another schema group.
+ */
+ public Table findTable(Table table) {
+ return findTable(table.getFullName());
+ }
+
+ /**
+ * Find the table with the given name in the group, using '.' as the
+ * catalog separator. Returns null if no table found.
+ */
+ public Table findTable(String name) {
+ if (name == null)
+ return null;
+
+ int dotIdx = name.indexOf('.');
+ if (dotIdx != -1) {
+ String schemaName = name.substring(0, dotIdx);
+ name = name.substring(dotIdx + 1);
+ Schema schema = getSchema(schemaName);
+ if (schema != null)
+ return schema.getTable(name);
+ } else {
+ Schema[] schemas = getSchemas();
+ Table tab;
+ for (int i = 0; i < schemas.length; i++) {
+ tab = schemas[i].getTable(name);
+ if (tab != null)
+ return tab;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return true if the given sequence is known to exist. While
+ * {@link #findSequence} may exhibit dynamic behavior in some schema group
+ * implementations, this method only returns true if the sequence has been
+ * added to this group or is known to exist in the database.
+ */
+ public boolean isKnownSequence(Sequence seq) {
+ return findSequence(seq) != null;
+ }
+
+ /**
+ * Return true if the given sequence is known to exist. While
+ * {@link #findSequence} may exhibit dynamic behavior in some schema group
+ * implementations, this method only returns true if the sequence has been
+ * added to this group or is known to exist in the database.
+ */
+ public boolean isKnownSequence(String name) {
+ return findSequence(name) != null;
+ }
+
+ /**
+ * Find the equivalent of the given sequence in this schema group. The
+ * given sequence that may have come from another schema group.
+ */
+ public Sequence findSequence(Sequence seq) {
+ return findSequence(seq.getFullName());
+ }
+
+ /**
+ * Find the sequence with the given name in the group, using '.' as the
+ * catalog separator. Returns null if no sequence found.
+ */
+ public Sequence findSequence(String name) {
+ if (name == null)
+ return null;
+
+ int dotIdx = name.indexOf('.');
+ if (dotIdx != -1) {
+ String schemaName = name.substring(0, dotIdx);
+ name = name.substring(dotIdx + 1);
+ Schema schema = getSchema(schemaName);
+ if (schema != null)
+ return schema.getSequence(name);
+ } else {
+ Schema[] schemas = getSchemas();
+ Sequence seq;
+ for (int i = 0; i < schemas.length; i++) {
+ seq = schemas[i].getSequence(name);
+ if (seq != null)
+ return seq;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Find all foreign keys exported by a given primary key (all foreign
+ * keys that link to the primary key).
+ */
+ public ForeignKey[] findExportedForeignKeys(PrimaryKey pk) {
+ if (pk == null)
+ return new ForeignKey[0];
+
+ Schema[] schemas = getSchemas();
+ Table[] tabs;
+ ForeignKey[] fks;
+ Collection exports = new LinkedList();
+ for (int i = 0; i < schemas.length; i++) {
+ tabs = schemas[i].getTables();
+ for (int j = 0; j < tabs.length; j++) {
+ fks = tabs[j].getForeignKeys();
+ for (int k = 0; k < fks.length; k++) {
+ if (fks[k].getPrimaryKeyTable() != null
+ && pk.equals(fks[k].getPrimaryKeyTable().
+ getPrimaryKey()))
+ exports.add(fks[k]);
+ }
+ }
+ }
+ return (ForeignKey[]) exports.toArray(new ForeignKey[exports.size()]);
+ }
+
+ /**
+ * Remove unreferenced or emtpy components from the schema.
+ */
+ public void removeUnusedComponents() {
+ Schema[] schemas = getSchemas();
+ Table[] tabs;
+ Column[] cols;
+ Sequence[] seqs;
+ PrimaryKey pk;
+ ForeignKey[] fks;
+ for (int i = 0; i < schemas.length; i++) {
+ seqs = schemas[i].getSequences();
+ for (int j = 0; j < seqs.length; j++)
+ if (seqs[j].getRefCount() == 0)
+ schemas[i].removeSequence(seqs[j]);
+
+ tabs = schemas[i].getTables();
+ for (int j = 0; j < tabs.length; j++) {
+ pk = tabs[j].getPrimaryKey();
+ fks = tabs[j].getForeignKeys();
+ cols = tabs[j].getColumns();
+
+ if (pk != null && pk.getRefCount() == 0)
+ tabs[j].removePrimaryKey();
+
+ for (int k = 0; k < fks.length; k++)
+ if (fks[k].getRefCount() == 0)
+ tabs[j].removeForeignKey(fks[k]);
+
+ for (int k = 0; k < cols.length; k++)
+ if (cols[k].getRefCount() == 0)
+ tabs[j].removeColumn(cols[k]);
+
+ if (tabs[j].getColumns().length == 0)
+ schemas[i].removeTable(tabs[j]);
+ }
+
+ if (schemas[i].getTables().length == 0)
+ removeSchema(schemas[i]);
+ }
+ }
+
+ public Object clone() {
+ SchemaGroup clone = newInstance();
+ clone.copy(this);
+ return clone;
+ }
+
+ /**
+ * Create a new instance of this class.
+ */
+ protected SchemaGroup newInstance() {
+ return new SchemaGroup();
+ }
+
+ /**
+ * Copy cloneable state from the given instance.
+ */
+ protected void copy(SchemaGroup group) {
+ Schema[] schemas = group.getSchemas();
+ for (int i = 0; i < schemas.length; i++)
+ importSchema(schemas[i]);
+
+ // have to do fks after all schemas are imported
+ Table[] tabs;
+ ForeignKey[] fks;
+ Schema clone;
+ for (int i = 0; i < schemas.length; i++) {
+ tabs = schemas[i].getTables();
+ for (int j = 0; j < tabs.length; j++) {
+ fks = tabs[j].getForeignKeys();
+ for (int k = 0; k < fks.length; k++)
+ getSchema(schemas[i].getName()).getTable
+ (tabs[j].getName()).importForeignKey(fks[k]);
+ }
+ }
+ }
+
+ /**
+ * Return a new schema with the given name.
+ */
+ protected Schema newSchema(String name) {
+ return new Schema(name, this);
+ }
+
+ /**
+ * Return a new sequence with the given name and owner schema.
+ */
+ protected Sequence newSequence(String name, Schema schema) {
+ return new Sequence(name, schema);
+ }
+
+ /**
+ * Return a new table with the given name and owner schema.
+ */
+ protected Table newTable(String name, Schema schema) {
+ return new Table(name, schema);
+ }
+
+ /**
+ * Return a new column with the given name and owner table.
+ */
+ protected Column newColumn(String name, Table table) {
+ return new Column(name, table);
+ }
+
+ /**
+ * Return a new primary key with the given name and owner table.
+ */
+ protected PrimaryKey newPrimaryKey(String name, Table table) {
+ return new PrimaryKey(name, table);
+ }
+
+ /**
+ * Return a new index with the given name and owner table.
+ */
+ protected Index newIndex(String name, Table table) {
+ return new Index(name, table);
+ }
+
+ /**
+ * Return a new unique constraint with the given name and owner table.
+ */
+ protected Unique newUnique(String name, Table table) {
+ return new Unique(name, table);
+ }
+
+ /**
+ * Return a new foreign key with the given name and owner table.
+ */
+ protected ForeignKey newForeignKey(String name, Table table) {
+ return new ForeignKey(name, table);
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaGroup.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaParser.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaParser.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaParser.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaParser.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import org.apache.openjpa.lib.meta.MetaDataParser;
+
+/**
+ * Interface class for parers that read schema information. Parsers
+ * will place all parsed schemas into the current {@link SchemaGroup}, set
+ * via the {@link #setSchemaGroup} method. This allows parsing of
+ * multiple files into a single schema group.
+ *
+ * @author Abe White
+ * @nojavadoc
+ */
+public interface SchemaParser
+ extends MetaDataParser {
+
+ /**
+ * Delay resolution of foreign key constraints until
+ * {@link #resolveConstraints} is called. This allows you to parse
+ * multiple resources where a foreign key in one resource might refer
+ * to a table in another.
+ */
+ public boolean getDelayConstraintResolve();
+
+ /**
+ * Delay resolution of foreign key constraints until
+ * {@link #resolveConstraints} is called. This allows you to parse
+ * multiple resources where a foreign key in one resource might refer
+ * to a table in another.
+ */
+ public void setDelayConstraintResolve(boolean delay);
+
+ /**
+ * Return the current schema group.
+ */
+ public SchemaGroup getSchemaGroup();
+
+ /**
+ * Set the current schema group; this clears all state from the last group.
+ */
+ public void setSchemaGroup(SchemaGroup group);
+
+ /**
+ * If this parser is in delayed resolve mode, resolve all constraints.
+ */
+ public void resolveConstraints();
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaParser.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaSerializer.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaSerializer.java?rev=423615&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaSerializer.java (added)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaSerializer.java Wed Jul 19 14:34:44 2006
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import org.apache.openjpa.lib.meta.MetaDataSerializer;
+
+/**
+ * Interface for schema serializers. Serializers work at the fine-grained
+ * fine-grained table level to allow you to split schemas among multiple files.
+ *
+ * @author Abe White
+ * @nojavadoc
+ */
+public interface SchemaSerializer
+ extends MetaDataSerializer {
+
+ /**
+ * Return the set of tables that will be serialized.
+ */
+ public Table[] getTables();
+
+ /**
+ * Add the given table to the set of tables that will be serialized.
+ */
+ public void addTable(Table table);
+
+ /**
+ * Remove the given table from the set to be serialized.
+ *
+ * @return true if table was removed, false if not in set
+ */
+ public boolean removeTable(Table table);
+
+ /**
+ * Add the given schema's objects to the set of objects that will be
+ * serialized.
+ */
+ public void addAll(Schema schema);
+
+ /**
+ * Add all the objects in the given group to the set of objects that
+ * will be serialized.
+ */
+ public void addAll(SchemaGroup group);
+
+ /**
+ * Remove the given schema's objects from the set to be serialized.
+ *
+ * @return true if any objects in schema removed, false if none in set
+ */
+ public boolean removeAll(Schema schema);
+
+ /**
+ * Remove all schemas in the given group from the set to be serialized.
+ *
+ * @return true if any objects in the group were removed, false if
+ * none in set
+ */
+ public boolean removeAll(SchemaGroup group);
+
+ /**
+ * Clear the set of objects to be serialized.
+ */
+ public void clear();
+}
Propchange: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaSerializer.java
------------------------------------------------------------------------------
svn:executable = *