From b1ed8b02118afd9385b550d02f40b7cf9a45439c Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Thu, 21 Dec 2006 20:53:55 +0000 Subject: [PATCH] Index handling. Automatic addition and removal of indices not yet implemented. --- .../jdbc/depot/DepotMarshaller.java | 35 +++++++++------ .../jdbc/depot/annotation/Entity.java | 3 ++ .../jdbc/depot/annotation/Index.java | 44 +++++++++++++++++++ 3 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 src/java/com/samskivert/jdbc/depot/annotation/Index.java diff --git a/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java b/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java index 7300ba6..56e02e4 100644 --- a/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java +++ b/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java @@ -41,6 +41,7 @@ import com.samskivert.jdbc.depot.annotation.Computed; import com.samskivert.jdbc.depot.annotation.Entity; import com.samskivert.jdbc.depot.annotation.GeneratedValue; import com.samskivert.jdbc.depot.annotation.Id; +import com.samskivert.jdbc.depot.annotation.Index; import com.samskivert.jdbc.depot.annotation.TableGenerator; import com.samskivert.jdbc.depot.annotation.Transient; @@ -72,6 +73,7 @@ public class DepotMarshaller _pclass = pclass; // see if this is a computed entity + Entity entity = pclass.getAnnotation(Entity.class); Computed computed = pclass.getAnnotation(Computed.class); if (computed == null) { // if not, this class has a corresponding SQL table @@ -79,7 +81,6 @@ public class DepotMarshaller _tableName = _tableName.substring(_tableName.lastIndexOf(".")+1); // see if there are Entity values specified - Entity entity = pclass.getAnnotation(Entity.class); if (entity != null) { if (entity.name().length() > 0) { _tableName = entity.name(); @@ -200,28 +201,34 @@ public class DepotMarshaller // figure out the list of fields that correspond to actual table columns and generate the // SQL used to create and migrate our table (unless we're a computed entity) _columnFields = new String[_allFields.length]; - _columnDefinitions = new String[_allFields.length]; int jj = 0; for (int ii = 0; ii < _allFields.length; ii++) { // include all persistent non-computed fields String colDef = _fields.get(_allFields[ii]).getColumnDefinition(); if (colDef != null) { _columnFields[jj] = _allFields[ii]; - _columnDefinitions[jj] = colDef; + _declarations.add(colDef); jj ++; } } _columnFields = ArrayUtil.splice(_columnFields, jj); - _columnDefinitions = ArrayUtil.splice(_columnDefinitions, jj); + + // determine whether we have any index definitions + if (entity != null) { + for (Index index : entity.indices()) { + // TODO: delegate this to a database specific SQL generator + _declarations.add("INDEX " + index.name() + " " + index.type() + + " (" + StringUtil.join(index.columns(), ", ") + ")"); + } + } // add the primary key, if we have one if (hasPrimaryKey()) { - String[] indices = new String[_pkColumns.size()]; - for (int ii = 0; ii < indices.length; ii ++) { - indices[ii] = _pkColumns.get(ii).getColumnName(); + String[] pkcols = new String[_pkColumns.size()]; + for (int ii = 0; ii < pkcols.length; ii ++) { + pkcols[ii] = _pkColumns.get(ii).getColumnName(); } - _columnDefinitions = ArrayUtil.append( - _columnDefinitions, "PRIMARY KEY (" + StringUtil.join(indices, ", ") + ")"); + _declarations.add("PRIMARY KEY (" + StringUtil.join(pkcols, ", ") + ")"); } // if we did not find a schema version field, complain @@ -582,10 +589,10 @@ public class DepotMarshaller ctx.invoke(new Modifier(null) { public int invoke (Connection conn) throws SQLException { if (!JDBCUtil.tableExists(conn, getTableName())) { - log.fine("Creating table " + getTableName() + " (" + - StringUtil.join(_columnDefinitions, ", ") + ") " + _postamble); - JDBCUtil.createTableIfMissing( - conn, getTableName(), _columnDefinitions, _postamble); + log.info("Creating table " + getTableName() + " (" + _declarations + ") " + + _postamble); + String[] definition = _declarations.toArray(new String[_declarations.size()]); + JDBCUtil.createTableIfMissing(conn, getTableName(), definition, _postamble); updateVersion(conn, 1); } return 0; @@ -752,7 +759,7 @@ public class DepotMarshaller protected int _schemaVersion = -1; /** Used when creating and migrating our table schema. */ - protected String[] _columnDefinitions; + protected ArrayList _declarations = new ArrayList(); /** Used when creating and migrating our table schema. */ protected String _postamble = ""; diff --git a/src/java/com/samskivert/jdbc/depot/annotation/Entity.java b/src/java/com/samskivert/jdbc/depot/annotation/Entity.java index 81ddb7f..db64452 100644 --- a/src/java/com/samskivert/jdbc/depot/annotation/Entity.java +++ b/src/java/com/samskivert/jdbc/depot/annotation/Entity.java @@ -35,6 +35,9 @@ public @interface Entity /** The name of an entity. Defaults to the unqualified name of the entity class. */ String name () default ""; + /** Defines indices to add to this entity's table. */ + Index[] indices () default {}; + /** Additional SQL to be added when creating this entity's table for the first time. You can * specify a MySQL table storage type for example. */ String postamble () default ""; diff --git a/src/java/com/samskivert/jdbc/depot/annotation/Index.java b/src/java/com/samskivert/jdbc/depot/annotation/Index.java new file mode 100644 index 0000000..f8bab77 --- /dev/null +++ b/src/java/com/samskivert/jdbc/depot/annotation/Index.java @@ -0,0 +1,44 @@ +// +// $Id$ +// +// samskivert library - useful routines for java programs +// Copyright (C) 2006 Michael Bayne +// +// 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, or +// (at your option) any later version. +// +// 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 + +package com.samskivert.jdbc.depot.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Defines an index on an entity table. + */ +@Target(value={}) +@Retention(value=RetentionPolicy.RUNTIME) +public @interface Index +{ + /** Defines the name of the index. */ + String name () default ""; + + /** Configures the type of this index if necessary. MySQL supports FULLTEXT, SPATIAL and + * UNIQUE. */ + String type () default ""; + + /** Defines the columns on which the index operates. */ + String[] columns () default {}; +}