/*
Copyright (c) 2008 Health Market Science, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
You can contact Health Market Science at info@healthmarketscience.com
or at the following address:
Health Market Science
2700 Horizon Drive
Suite 200
King of Prussia, PA 19406
*/
package com.healthmarketscience.sqlbuilder.dbspec.basic;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Root object for a collection of db objects all residing in the same
* logical database.
* <p>
* Note, you generally do not want to mix objects from different specs because
* they may have conflicting aliases.
* <p>
* The DbSpec also acts as the "factory" for creating other DbObject instances
* (via the various {@code create*()} methods). All the other DbObject types
* delegate object creation to the referenced DbSpec. Thus, custom model
* classes can easily be plugged in by creating a subclass of this class which
* overrides the relevant creation methods.
*
* @author James Ahlborn
*/
public class DbSpec implements Serializable {
/** schemas currently created for this db spec */
private final List<DbSchema> _schemas = new ArrayList<DbSchema>();
/** joins currently created for this db spec */
private final List<DbJoin> _joins = new ArrayList<DbJoin>();
/** unique id for the next alias for this db spec */
private int _nextAliasNum;
public DbSpec() {
}
public List<DbSchema> getSchemas() {
return _schemas;
}
public List<DbJoin> getJoins() {
return _joins;
}
/**
* @return the next unused alias for this group of db objects
*/
public String getNextAlias() {
return "t" + _nextAliasNum++;
}
/**
* @return the default schema previously added to this spec, or {@code null}
* if none.
*/
public DbSchema getDefaultSchema() {
return findSchema(null);
}
/**
* @param name name of the schema to find
* @return the schema previously added to this spec with the given name, or
* {@code null} if none.
*/
public DbSchema findSchema(String name) {
return DbObject.findObject(_schemas, name);
}
/**
* Creates and adds a schema with no name to this spec (often referred to as
* the default schema).
* <p>
* Note, no effort is made to make sure the schema is unique.
* @return the freshly created default schema
*/
public DbSchema addDefaultSchema() {
return addSchema((String)null);
}
/**
* Creates and adds a schema with the given name to this spec.
* <p>
* Note, no effort is made to make sure the given name is unique.
* @param name the name of the new schema
* @return the freshly created schema
*/
public DbSchema addSchema(String name) {
DbSchema schema = createSchema(name);
return addSchema(schema);
}
/**
* Adds the given schema to this schema.
* <p>
* Note, no effort is made to make sure the given schema is unique.
* @param schema the schema to be added
* @return the given schema
*/
public <T extends DbSchema> T addSchema(T schema) {
_schemas.add(checkOwnership(schema));
return schema;
}
/**
* Creates and adds a join with the given parameters to this spec.
* <p>
* Note, no effort is made to make sure the given join is unique.
* @param schemaFrom schema for the left side of the join
* @param tableFrom table for the left side of the join
* @param schemaTo schema for the right side of the join
* @param tableTo table for the right side of the join
* @param colNames the column names for the join (same for both tables)
* @return the freshly created schema
*/
public DbJoin addJoin(String schemaFrom, String tableFrom,
String schemaTo, String tableTo,
String... colNames)
{
return addJoin(schemaFrom, tableFrom, schemaTo, tableTo,
colNames, colNames);
}
/**
* Creates and adds a join with the given parameters to this spec.
* <p>
* Note, no effort is made to make sure the given join is unique.
* @param schemaFrom schema for the left side of the join
* @param tableFrom table for the left side of the join
* @param schemaTo schema for the right side of the join
* @param tableTo table for the right side of the join
* @param fromColNames the column names for the left side of the join
* @param toColNames the column names for the right side of the join
* @return the freshly created schema
*/
public DbJoin addJoin(String schemaFrom, String tableFrom,
String schemaTo, String tableTo,
String[] fromColNames, String[] toColNames)
{
DbJoin join = createJoin(findSchema(schemaFrom).findTable(tableFrom),
findSchema(schemaTo).findTable(tableTo),
fromColNames, toColNames);
return addJoin(join);
}
/**
* Adds the given join to this schema.
* <p>
* Note, no effort is made to make sure the given join is unique.
* @param join the join to be added
* @return the given join
*/
public <T extends DbJoin> T addJoin(T join) {
_joins.add(checkOwnership(join));
return join;
}
/**
* Creates and returns a new {@link DbSchema} with the given parameters.
* <p>
* This method can be overriden to utilize custom model subclasses.
*/
public DbSchema createSchema(String name)
{
return new DbSchema(this, name);
}
/**
* Creates and returns a new {@link DbTable} with the given parameters.
* <p>
* This method can be overriden to utilize custom model subclasses.
*/
public DbTable createTable(DbSchema parent, String name)
{
return new DbTable(parent, name);
}
/**
* Creates and returns a new {@link DbColumn} with the given parameters.
* <p>
* This method can be overriden to utilize custom model subclasses.
*/
public DbColumn createColumn(DbTable parent, String name,
String typeName, Integer typeLength, Integer scale)
{
return new DbColumn(parent, name, typeName, typeLength, scale);
}
/**
* Creates and returns a new {@link DbJoin} with the given parameters.
* <p>
* This method can be overriden to utilize custom model subclasses.
*/
public DbJoin createJoin(DbTable fromTable, DbTable toTable,
String[] fromColNames, String[] toColNames)
{
return new DbJoin(this, fromTable, toTable, fromColNames, toColNames);
}
/**
* Creates and returns a new {@link DbIndex} with the given parameters.
* <p>
* This method can be overriden to utilize custom model subclasses.
*/
public DbIndex createIndex(DbTable table, String name, String... colNames)
{
return new DbIndex(table, name, colNames);
}
/**
* Creates and returns a new {@link DbFunctionPackage} with the given
* parameters.
* <p>
* This method can be overriden to utilize custom model subclasses.
*/
public DbFunctionPackage createFunctionPackage(DbSchema parent, String name)
{
return new DbFunctionPackage(parent, name);
}
/**
* Creates and returns a new {@link DbFunction} with the given parameters.
* <p>
* This method can be overriden to utilize custom model subclasses.
*/
public DbFunction createFunction(DbFunctionPackage parent, String name)
{
return new DbFunction(parent, name);
}
/**
* Creates and returns a new column {@link DbConstraint} with the given
* parameters.
* <p>
* This method can be overriden to utilize custom model subclasses.
*/
public DbConstraint createColumnConstraint(
DbColumn parent, String name,
com.healthmarketscience.sqlbuilder.dbspec.Constraint.Type type)
{
return new DbConstraint(parent, name, type);
}
/**
* Creates and returns a new table {@link DbConstraint} with the given
* parameters.
* <p>
* This method can be overriden to utilize custom model subclasses.
*/
public DbConstraint createTableConstraint(
DbTable parent, String name,
com.healthmarketscience.sqlbuilder.dbspec.Constraint.Type type,
String... colNames)
{
return new DbConstraint(parent, name, type, colNames);
}
/**
* Creates and returns a new column {@link DbForeignKeyConstraint} with the
* given parameters.
* <p>
* This method can be overriden to utilize custom model subclasses.
*/
public DbForeignKeyConstraint createColumnForeignKeyConstraint(
DbColumn parent, String name, DbTable referencedTable, String refColName)
{
return new DbForeignKeyConstraint(parent, name, referencedTable,
refColName);
}
/**
* Creates and returns a new table {@link DbForeignKeyConstraint} with the
* given parameters.
* <p>
* This method can be overriden to utilize custom model subclasses.
*/
public DbForeignKeyConstraint createTableForeignKeyConstraint(
DbTable parent, String name, DbTable referencedTable,
String[] colNames, String[] refColNames)
{
return new DbForeignKeyConstraint(parent, name, referencedTable,
colNames, refColNames);
}
/**
* @throws IllegalArgumentException if the parent of the given object is not
* this object
*/
protected <T extends DbObject<?>> T checkOwnership(T obj) {
if(obj.getSpec() != this) {
throw new IllegalArgumentException(
"Given " + obj.getClass().getSimpleName() + " is not owned by this " +
getClass().getSimpleName());
}
return obj;
}
}