diff --git a/bin/runjava b/bin/runjava index 29176914..0b846b08 100755 --- a/bin/runjava +++ b/bin/runjava @@ -1,103 +1,21 @@ -#!/usr/bin/perl -w +#!/bin/sh +# +# Runs built code -use Getopt::Std; +ROOT=`dirname $0` +ROOT=`cd $ROOT/.. ; pwd` -my $usage = "Usage: $0 [-p pid_file] [-r server_root] args\n"; +JAVA_VM="$JAVA_HOME/bin/java" +if [ ! -e $JAVA_VM ]; then + echo "$0: Cannot find JVM in $JAVA_HOME. Exiting." + exit 255 +fi -# locations of stuff -chomp($location = `dirname $0`); +CLASSPATH="$JAVA_HOME/jre/lib/rt.jar" +for JAR in $ROOT/dist/lib/*.jar; do + CLASSPATH=$CLASSPATH:$JAR +done +CLASSPATH=$ROOT/dist/classes:$CLASSPATH +export CLASSPATH -# get the server root by popping the /bin off of our parent directory -@parts = split(/\//, $location); -pop(@parts); -my $root = join("/", @parts); - -my $jhome = $ENV{"JAVA_HOME"}; - -# make sure JAVA_HOME is set -if (!defined $jhome) { - warn "$0: Error: No JAVA_HOME specified!\n"; - warn "\n"; - warn "You must set your JAVA_HOME environment variable to the\n"; - warn "the absolute path of your JDK installation. For example:\n"; - warn "\n"; - warn " % JAVA_HOME=/usr/local/jdk1.2\n"; - warn " % export JAVA_HOME\n"; - die "\n"; -} - -# make sure it's set to a directory -if (! -d $jhome) { - die "$0: Can't find a java interpreter in '$jhome'.\n"; -} - -my $java = "$jhome/bin/java"; -my $jlib = "$jhome/lib/classes.zip"; - -# determine our machine architecture -my $ostype = `uname -s`; -my $machtype = `uname -m`; -chomp($ostype); -chomp($machtype); -my $arch = "$machtype-$ostype"; - -# add our native libraries to the runtime library path -my $libs = "$root/lib/$arch"; -my $libpath = $ENV{"LD_LIBRARY_PATH"}; - -if (defined $libpath) { - $ENV{"LD_LIBRARY_PATH"} = "$libs:$libpath"; -} else { - $ENV{"LD_LIBRARY_PATH"} = $libs; -} - -# put everything in our class path -my $classpath = "-classpath $jlib:$root/dist/classes"; - -# any zip or jar files in our lib/ directory get added to the class path -if (opendir(DIR, "$root/lib")) { - foreach $lib (grep { /.(zip|jar)/ && -f "$root/lib/$_" } readdir(DIR)) { - $classpath .= ":$root/lib/$lib"; - } - closedir DIR; -} - -# specify our server root (this is for server code) -my $serverroot = "-Dserver.root=$root"; - -# specify our base directory (this is for client code) -my $basedir = "-Dbase.dir=$root/src/java"; - -my $pid_file = undef; -my $i = 0; - -# strip out the -p and -r args (we'd use getopt() but the damned thing -# provides no way of escaping arguments so that we can pass args to -# runjava that get passed down to the JVM) -for ($i = 0; $i < @ARGV; $i++) { - my $arg = $ARGV[$i]; - - # stop when we see -- (and strip it out because Java don't dig --) - if ($arg eq "--") { - splice(@ARGV, $i, 1); - last; - } - - if ($arg eq "-p") { - $pid_file = $ARGV[$i+1]; - splice(@ARGV, $i, 2); - $i -= 1; # decrement i so that things stay in sync - - } elsif ($arg eq "-r") { - $serverroot = "-Dserver.root=" . $ARGV[$i+1]; - splice(@ARGV, $i, 2); - $i -= 1; # decrement i so that things stay in sync - } -} - -# log the pid file if requested to do so -print `echo $$ > $pid_file` if (defined $pid_file); - -my $cmd = "$java -mx256M $classpath $serverroot $basedir " . join(" ", @ARGV); -# print "$cmd\n"; -exec($cmd); +eval $JAVA_VM $JAVA_ARGS "$@" diff --git a/bin/runtest b/bin/runtest new file mode 100644 index 00000000..a285c5af --- /dev/null +++ b/bin/runtest @@ -0,0 +1,21 @@ +#!/bin/sh +# +# Runs test code + +ROOT=`dirname $0` +ROOT=`cd $ROOT/.. ; pwd` + +JAVA_VM="$JAVA_HOME/bin/java" +if [ ! -e $JAVA_VM ]; then + echo "$0: Cannot find JVM in $JAVA_HOME. Exiting." + exit 255 +fi + +CLASSPATH="$JAVA_HOME/jre/lib/rt.jar" +for JAR in $ROOT/dist/lib/*.jar; do + CLASSPATH=$CLASSPATH:$JAR +done +CLASSPATH=$ROOT/tests/dist/classes:$ROOT/dist/classes:$ROOT/tests:$CLASSPATH +export CLASSPATH + +eval $JAVA_VM $JAVA_ARGS "$@" diff --git a/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java b/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java index 7300ba68..56e02e44 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 81ddb7f9..db644520 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 00000000..f8bab779 --- /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 {}; +} diff --git a/tests/build.xml b/tests/build.xml index 6f024f3b..3cfb7eee 100644 --- a/tests/build.xml +++ b/tests/build.xml @@ -50,7 +50,6 @@ - diff --git a/tests/src/java/com/samskivert/jdbc/depot/TestRecord.java b/tests/src/java/com/samskivert/jdbc/depot/TestRecord.java index 8ff0145b..7ab5bf19 100644 --- a/tests/src/java/com/samskivert/jdbc/depot/TestRecord.java +++ b/tests/src/java/com/samskivert/jdbc/depot/TestRecord.java @@ -6,14 +6,17 @@ package com.samskivert.jdbc.depot; import java.sql.Date; import java.sql.Timestamp; -import com.samskivert.jdbc.depot.annotation.Id; import com.samskivert.jdbc.depot.annotation.Column; +import com.samskivert.jdbc.depot.annotation.Entity; +import com.samskivert.jdbc.depot.annotation.Id; +import com.samskivert.jdbc.depot.annotation.Index; import com.samskivert.util.StringUtil; /** * A test persistent object. */ +@Entity(indices={ @Index(name="createdIndex", columns={"created"}) }) public class TestRecord { public static final int SCHEMA_VERSION = 1;