initial checkin

only works for standalone tests, plugin not supported yet
This commit is contained in:
zzz
2023-12-17 10:09:27 -05:00
parent d014e94a7e
commit 1f8cf91407
10 changed files with 3094 additions and 0 deletions

2
CHANGES.txt Normal file
View File

@ -0,0 +1,2 @@
2023-12-17 0.0.1
- Initial checkin

17
LICENSE.txt Normal file
View File

@ -0,0 +1,17 @@
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.
========================================================================
Includes code from syndie 1.107 (Public Domain)
Includes sqlite-jdbc-3.44.0.0.jar from https://github.com/xerial/sqlite-jdbc (Apache 2.0)

108
build.xml Normal file
View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<project basedir="." default="all" name="sqldb">
<property file="override.properties"/>
<property name="release.number" value="0.1.0" />
<property name="jdbc.version" value="3.44.1.0" />
<property name="jdbc.lib" value="lib/sqlite-jdbc-${jdbc.version}.jar" />
<property name="jdbc.url" value="https://github.com/xerial/sqlite-jdbc/releases/download/${jdbc.version}/sqlite-jdbc-${jdbc.version}.jar" />
<condition property="lib.available" >
<available file="${jdbc.lib}" type="file" />
</condition>
<target name="all" depends="clean,plugin" />
<target name="jar" >
<ant dir="src" target="build" />
</target>
<target name="plugin" depends="fetchlib, jar">
<mkdir dir="plugin/" />
<mkdir dir="plugin/lib/" />
<delete>
<!-- in installer but not update -->
<fileset dir="plugin/lib/" includes="sqlite-jdbc.jar" />
</delete>
<!-- get version number -->
<buildnumber file="scripts/build.number" />
<!-- make the update xpi2p -->
<!-- this contains everything except i2ptunnel.config -->
<copy file="LICENSE.txt" todir="plugin/" overwrite="true" />
<copy file="README.txt" todir="plugin/" overwrite="true" />
<copy file="CHANGES.txt" todir="plugin/" overwrite="true" />
<copy file="scripts/plugin.config" todir="plugin/" overwrite="true" />
<exec executable="echo" osfamily="unix" failonerror="true" output="plugin/plugin.config" append="true">
<arg value="update-only=true" />
</exec>
<exec executable="echo" osfamily="unix" failonerror="true" output="plugin/plugin.config" append="true">
<arg value="version=${release.number}-b${build.number}" />
</exec>
<!-- pull out musl and android -->
<jar destfile="plugin/lib/sqlite-jdbc.jar" manifest="${jdbc.lib}" filesetmanifest="mergewithoutmain" >
<zipfileset excludes="org/sqlite/native/Linux-Android org/sqlite/native/Linux-Android/**/* org/sqlite/native/Linux-Musl org/sqlite/native/Linux-Musl/**/* org/sqlite/native/Linux/ppc64 org/sqlite/native/Linux/ppc64/* org/sqlite/native/*/x86/ org/sqlite/native/*/x86/*" src="${jdbc.lib}" />
</jar>
<copy file="src/build/sqldb.jar" todir="plugin/lib/" />
<copy file="/usr/share/java/slf4j-api.jar" todir="plugin/lib/" />
<input message="Enter su3 signing key password:" addproperty="release.password.su3" />
<fail message="You must enter a password." >
<condition>
<equals arg1="${release.password.su3}" arg2=""/>
</condition>
</fail>
<!-- this will fail if no su3 keys exist, as it needs the password twice -->
<exec executable="scripts/makeplugin.sh" inputstring="${release.password.su3}" failonerror="true" >
<arg value="plugin" />
</exec>
<move file="sqldb.su3" tofile="sqldb-update.su3" overwrite="true" />
<!-- make the install xpi2p -->
<copy file="scripts/plugin.config" todir="plugin/" overwrite="true" />
<!-- Files in installer but not update. Be sure to Add to delete fileset above and clean target below -->
<exec executable="echo" osfamily="unix" failonerror="true" output="plugin/plugin.config" append="true">
<arg value="version=${release.number}-b${build.number}" />
</exec>
<exec executable="scripts/makeplugin.sh" inputstring="${release.password.su3}" failonerror="true" >
<arg value="plugin" />
</exec>
</target>
<target name="fetchlib" unless="lib.available" >
<echo message="It seems that you don't have '${jdbc.lib}' deployed." />
<echo message="The build script can download this file for you automatically," />
<echo message="or alternatively you can obtain it manually from:" />
<echo message="${jdbc.url}" />
<echo message="" />
<input message="Download JDBC library automatically?" validargs="y,n" addproperty="jdbc.download" />
<fail message="Aborting as requested. Please deploy the Jetty archive manually." >
<condition>
<equals arg1="${jdbc.download}" arg2="n"/>
</condition>
</fail>
<mkdir dir="lib/" />
<get src="${jdbc.url}" verbose="true" dest="${jdbc.lib}" />
</target>
<target name="distclean" depends="clean" />
<target name="clean" >
<ant dir="src" target="clean" />
<defaultexcludes remove="**/*~"/>
<delete>
<fileset dir="." includes="*/*.~ **/*.*~ */**/*.*~ *.*~" />
</delete>
<delete file="plugin/plugin.config" />
<delete dir="plugin/lib/" />
<delete file="plugin/CHANGES.txt" />
<delete file="plugin/LICENSE.txt" />
<delete file="plugin/README.txt" />
<delete file="sqldb.xpi2p" />
<delete file="sqldb-update.xpi2p" />
<delete file="sqldb.su3" />
<delete file="sqldb-update.su3" />
<delete file="plugin.zip" />
<delete dir="plugin/" />
</target>
</project>

47
resources/ddl_update0.txt Normal file
View File

@ -0,0 +1,47 @@
--
-- Version 1 sqlite3 database schema
--
-- this is the magic that makes it not dog slow
-- https://www.sqlite.org/wal.html
PRAGMA journal_mode = WAL;
BEGIN TRANSACTION;
-- info table
CREATE TABLE info ("key" TEXT PRIMARY KEY NOT NULL, "value" TEXT NOT NULL);
INSERT INTO info VALUES('version', '1');
INSERT INTO info VALUES('created', unixepoch("now"));
INSERT INTO info VALUES('upgraded', unixepoch("now"));
-- lists table
-- dots in a table name is really bad
-- there must be a way to escape it but let's just map to an internal name
CREATE TABLE lists ("list" TEXT PRIMARY KEY NOT NULL, "internal" TEXT NOT NULL);
INSERT INTO lists VALUES('privatehosts.txt', 'privatehoststxt');
INSERT INTO lists VALUES('userhosts.txt', 'userhoststxt');
INSERT INTO lists VALUES('hosts.txt', 'hoststxt');
-- list tables
-- hostname to primary entry (preferred, usually non-DSA) and optional alt (DSA) entry numbers
CREATE TABLE "privatehoststxt" ("hostname" TEXT PRIMARY KEY NOT NULL, "entry" INTEGER NOT NULL, "alt" INTEGER);
CREATE TABLE "userhoststxt" ("hostname" TEXT PRIMARY KEY NOT NULL, "entry" INTEGER NOT NULL, "alt" INTEGER);
CREATE TABLE "hoststxt" ("hostname" TEXT PRIMARY KEY NOT NULL, "entry" INTEGER NOT NULL, "alt" INTEGER);
-- entry table
-- id to dest, added time, modified time, notes, source, verified
-- Don't use AUTOINCREMENT
-- https://www.sqlite.org/autoinc.html
-- CREATE TABLE entries ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "dest" BLOB NOT NULL, "a" DATETIME NOT NULL, "m" DATETIME, "notes" TEXT, "s" TEXT, "v" BOOLEAN NOT NULL);
CREATE TABLE entries ("id" INTEGER PRIMARY KEY NOT NULL, "dest" BLOB NOT NULL, "a" DATETIME NOT NULL, "m" DATETIME, "notes" TEXT, "s" TEXT, "v" BOOLEAN NOT NULL);
-- reverse lookup table
-- first 8 bytes of hash to comma separated list of hostnames
CREATE TABLE "reverse" ("hash" INTEGER PRIMARY KEY NOT NULL, "hostnames" TEXT NOT NULL);
COMMIT TRANSACTION;
-- https://www.sqlite.org/pragma.html#synchronous
PRAGMA main.synchronous = NORMAL;
-- https://www.sqlite.org/pragma.html#pragma_wal_checkpoint
PRAGMA main.wal_checkpoint(FULL);

147
scripts/makeplugin.sh Executable file
View File

@ -0,0 +1,147 @@
#!/bin/sh
#
# basic packaging up of a plugin
#
# usage: makeplugin.sh plugindir
#
# zzz 2010-02
# zzz 2014-08 added support for su3 files
#
if [ -z "$I2P" -a -d "$PWD/../i2p.i2p/pkg-temp" ]; then
export I2P=../i2p.i2p/pkg-temp
fi
if [ ! -d "$I2P" ]; then
echo "Can't locate your I2P installation. Please add a environment variable named I2P with the path to the folder as value"
echo "On OSX this solved with running: export I2P=/Applications/i2p if default install directory is used."
exit 1
fi
PUBKEYDIR=$HOME/.i2p-plugin-keys
PUBKEYFILE=$PUBKEYDIR/plugin-public-signing.key
PRIVKEYFILE=$PUBKEYDIR/plugin-private-signing.key
B64KEYFILE=$PUBKEYDIR/plugin-public-signing.txt
PUBKEYSTORE=$PUBKEYDIR/plugin-su3-public-signing.crt
PRIVKEYSTORE=$PUBKEYDIR/plugin-su3-keystore.ks
KEYTYPE=RSA_SHA512_4096
PLUGINDIR=${1:-plugin}
PC=plugin.config
PCT=${PC}.tmp
if [ ! -d $PLUGINDIR ]
then
echo "You must have a $PLUGINDIR directory"
exit 1
fi
if [ ! -f $PLUGINDIR/$PC ]
then
echo "You must have a $PLUGINDIR/$PC file"
exit 1
fi
SIGNER=`grep '^signer=' $PLUGINDIR/$PC`
if [ "$?" -ne "0" ]
then
echo "You must have a plugin name in $PC"
echo 'For example name=foo'
exit 1
fi
SIGNER=`echo $SIGNER | cut -f 2 -d '='`
if [ ! -f $PRIVKEYFILE ]
then
echo "Creating new XPI2P DSA keys"
mkdir -p $PUBKEYDIR || exit 1
java -cp $I2P/lib/i2p.jar net.i2p.crypto.TrustedUpdate keygen $PUBKEYFILE $PRIVKEYFILE || exit 1
java -cp $I2P/lib/i2p.jar net.i2p.data.Base64 encode $PUBKEYFILE $B64KEYFILE || exit 1
rm -rf logs/
chmod 444 $PUBKEYFILE $B64KEYFILE
chmod 400 $PRIVKEYFILE
echo "Created new XPI2P keys: $PUBKEYFILE $PRIVKEYFILE"
fi
if [ ! -f $PRIVKEYSTORE ]
then
echo "Creating new SU3 $KEYTYPE keys for $SIGNER"
java -cp $I2P/lib/i2p.jar net.i2p.crypto.SU3File keygen -t $KEYTYPE $PUBKEYSTORE $PRIVKEYSTORE $SIGNER || exit 1
echo '*** Save your password in a safe place!!! ***'
rm -rf logs/
# copy to the router dir so verify will work
CDIR=$I2P/certificates/plugin
mkdir -p $CDIR || exit 1
CFILE=$CDIR/`echo $SIGNER | sed s/@/_at_/`.crt
cp $PUBKEYSTORE $CFILE
chmod 444 $PUBKEYSTORE
chmod 400 $PRIVKEYSTORE
chmod 644 $CFILE
echo "Created new SU3 keys: $PUBKEYSTORE $PRIVKEYSTORE"
echo "Copied public key to $CFILE for testing"
fi
rm -f plugin.zip
OPWD=$PWD
cd $PLUGINDIR
grep -q '^name=' $PC
if [ "$?" -ne "0" ]
then
echo "You must have a plugin name in $PC"
echo 'For example name=foo'
exit 1
fi
grep -q '^version=' $PC
if [ "$?" -ne "0" ]
then
echo "You must have a version in $PC"
echo 'For example version=0.1.2'
exit 1
fi
# update the date
grep -v '^date=' $PC > $PCT
DATE=`date '+%s000'`
echo "date=$DATE" >> $PCT
mv $PCT $PC || exit 1
# add our Base64 key
grep -v '^key=' $PC > $PCT
B64KEY=`cat $B64KEYFILE`
echo "key=$B64KEY" >> $PCT || exit 1
mv $PCT $PC || exit 1
# zip it
zip -r $OPWD/plugin.zip * || exit 1
# get the version and use it for the sud header
VERSION=`grep '^version=' $PC | cut -f 2 -d '='`
# get the name and use it for the file name
NAME=`grep '^name=' $PC | cut -f 2 -d '='`
XPI2P=${NAME}.xpi2p
SU3=${NAME}.su3
cd $OPWD
# sign it
echo "Signing version $VERSION by $SIGNER"
java -cp $I2P/lib/i2p.jar net.i2p.crypto.TrustedUpdate sign plugin.zip $XPI2P $PRIVKEYFILE $VERSION || exit 1
java -cp $I2P/lib/i2p.jar net.i2p.crypto.SU3File sign -c PLUGIN -t $KEYTYPE plugin.zip $SU3 $PRIVKEYSTORE $VERSION $SIGNER || exit 1
rm -f plugin.zip
# verify
echo 'Verifying. ...'
java -cp $I2P/lib/i2p.jar net.i2p.crypto.TrustedUpdate showversion $XPI2P || exit 1
java -cp $I2P/lib/i2p.jar -Drouter.trustedUpdateKeys=$B64KEY net.i2p.crypto.TrustedUpdate verifysig $XPI2P || exit 1
java -cp $I2P/lib/i2p.jar net.i2p.crypto.SU3File showversion $SU3 || exit 1
java -cp $I2P/lib/i2p.jar net.i2p.crypto.SU3File verifysig -k $PUBKEYSTORE $SU3 || exit 1
rm -rf logs/
echo 'Plugin files created: '
wc -c $XPI2P
wc -c $SU3
exit 0

15
scripts/plugin.config Normal file
View File

@ -0,0 +1,15 @@
name=sqldb
signer=zzz-plugin@mail.i2p
consoleLinkName=SQLDB
consoleLinkURL=/dns
consoleLinkTooltip=sqlite3 addressbook database
icon-code=iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABm1BMVEUAAAAZGRkZGRkaGhoZGRkZGRkZGRkZGRkYGBgZGRkYGBgZGRkYGBgZGRkZGRkXFxcYGBgZGRkZGRkZGRkZGRkAAAAZGRnziRYTExPzfhbzbhbzdxbzgxbzlRYLCwvzjhbzcxbMzMzzkBb~~~~~~Pl0dHRdXV3GxsYnJyfe3t7OycbBwcGcnJyHh4cjEgP39~f96dSurq5~f397e3tra2tlZWU7OzseHh7haRSGSAsOBwGpqKeWlpbgpnRUVFRNTU00NDTxmynPbRJwNgpXLwdEJQY4IAUVCwLy8vL83sK7u7uysrL7yqf6v5Tdr4H4t3H4rGz2pEvnjUnqnkQvLy~zii30gyjxdCLqdhXLexK9bhGQTQ1-QAtlLgn-9u~Pxr7Uvqr71KbYuJz6yZn5v4T3pVv3s1rkmVr1nzr1kzLyjiPzex~pbBXJYxLJXRK~XxG4aBCYRQ5iNQlMKgctGgT7-~vas4zhnGj2qlNERETlhRTefxTedRTVfxOsZhC0YBC4UhCpWw9wQgr4sH~kqF7sizVpSyfWXxOZVw56Yx8pAAAAFXRSTlMAjPQOr8vV7eVwaVtPNyUa27WCwoZvol0xAAAEx0lEQVRYw72XZ1PbQBCGXQEnVMNJAjtyjpPcbWxsMB2SQOg1tCT0EiA9kN578rOzd4eQZUuO8iXPjGfkmdv3dm-v7DqsaKht8XhrBKDG6~HXNjj-iTpnlVBClbPOrrXb18htJElmSNK5hs9tx9zp4saCXOgOq6qaH-qWkCQzEZf~rxKXqvnU0c6pCUKIohDKREKNckeqL1U0r~cyc6kzRpTJg8OTILBysji~nyEkpnKJ5npr-8suZp7sUHbvXTFybX6SvEhKVMJ12creSaeXUx1bB6utJqzsKx0pthZOc3sPnX4kpsw-uNozmr5xtZzVGRIboU54zOyb6PQ5kjkWxbdphNBd0YTFDFGpE03m88v9ZD8Ew04R8Fw0I7RLsrKZD05qH1EWqKePEUNz~GGPIY4FMkUVnCXrT-2nlMNWyhhirLM~66MIpZ-0FnGoJKjCZUP-XWCfJTx3txHnNvt3hoBxQ0rvKf2g4CreD83ggErmg4xRxPkUBE7ZZ1~QwALJgQveov0L9iNkpo3Rg855Bn82-Odmm5FZMgIKF7vaXQ0BxDIil7-rCWzo39eDRsRMDIKo1k6WHxxIkcV2TloTGG3~iDjP20s5VlJ6JtywglLHTIDzCHHo2mtfvYEyZjskWEfugg8cSCqrAc4NdEGf9tFTLvBgKwku-JhAFazAi93QOeOojLGQCQfUhUZ2~7EUnoicp6icL6IJ95VOcKGOb2I5NqklaBOZkN589ritlJmYDMvII4iSBW2f9iErxt63GlgkURZDAzigkmtXOHeQNaNXjLAYGhy1sASJjCZ7iiqwbnRhcgoup1pHiyCgiVktMMsI-N428G0C0UVogl1E5kWOdQQmV8xrIkhwsXgFqZu8DnG-oop8CBVzTLolOJI1gjxEVq5yxlFFjBdtgIRlocYBSciTVf0cVOTs7qOAjqLCTnCwLLZzepENbn79-JYP39IEwttBThrZ5IwNx2FNIM7z8gvZ5jMMX8NDIEAXcRgHGbYi0O~LFfwGFpGmcRnznTyGbMJv7Ft4mabRAxsJL7VSxpFtrsPwIww3QhM9zSjxir1AyD70sRpMwFZuYYdpYI~vY~uIwE5SpoepAQS64iLw-98E7rMsQvnXKEgFvAQubSLb9MHwI1yQhKrzKy37EhblJrJNLwzfmz6~0upYDJDIPmSTsQ-0aGIRsOKzkVYGg8H3yB7jX4KUOSzzCPjD0rm99hnZ4sbDNspaPAcO-PSnLTLYa-ckbmjP7FxEpk-bXt7k8c-~GffeCV1wC-fBAX~x8z7dX3HmJ-uGl3Eny5734gIjilXruAMlzOEoLzA0vDSVeBhZ8DRk5DtLYXNpkZWKdFsJiAZu4RQrssrKvGTCQsH4si7FB1iZZ1JoDuBhq9OvcxRPskLTtNRN4Zz5~aMzx~wXPBbFdhj3Ryt58GMHd-nFtpkP0SzOSWX3TxtnbRBPR1m5X6nhyEciaonEO17UDG5H8rzhqNjyyHIO44FhuViAbt6X8Uhn5ZYHqG8WmER4GuN-dWhEYq4Ull7txXG2izdd3nobbZ8sF8LJBGZE4JcY6CrYavsAt98lcA0kLb8ZCofDw8sSor4DLqfbVutbZd76Nvrc~6P51tt~v97-t1i3~38A57d5M52iLPcAAAAASUVORK5CYII=
description=BitTorrent OpenTracker
author=zzz
updateURL=http://stats.i2p/i2p/plugins/sqldb-update.xpi2p
updateURL.su3=http://stats.i2p/i2p/plugins/sqldb-update.su3
websiteURL=http://zzz.i2p/forums/16
license=Apache 2.0
min-jetty-version=9
min-i2p-version=0.9.31
update-only=true

49
src/build.xml Normal file
View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="all" name="i2psnark">
<property name="i2pbase" value="../../i2p.i2p"/>
<property name="i2plib" value="${i2pbase}/build"/>
<path id="cp">
<pathelement path="${java.class.path}" />
<pathelement location="${i2plib}/i2p.jar" />
<pathelement location="${ant.home}/lib/ant.jar"/>
</path>
<target name="all" depends="clean, build" />
<target name="build" depends="jar" />
<target name="builddep">
</target>
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.8" />
<target name="compile">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac
srcdir="./java"
debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
destdir="./build/obj"
includeAntRuntime="false"
classpath="${i2plib}/i2p.jar" >
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
<target name="jar" depends="builddep, compile">
<mkdir dir="build/obj/net/i2p/client/naming/sqldb/resources" />
<copy todir="build/obj/net/i2p/client/naming/sqldb/resources" >
<fileset dir="../resources" />
</copy>
<jar destfile="build/sqldb.jar" basedir="./build/obj" includes="**/*.class **/resources/*" >
</jar>
</target>
<target name="clean">
<delete dir="./build" />
</target>
<target name="cleandep" depends="clean">
</target>
<target name="distclean" depends="clean">
</target>
</project>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,143 @@
package net.i2p.client.naming.sqldb;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
/**
* Initialize the database, creating and updating to the latest version if necessary
*
* Adapted from syndie (public domain)
*/
class DBInit {
private final Connection _con;
private final Log _log;
private static final String DDL_PREFIX = "/net/i2p/client/naming/sqldb/resources/ddl_update";
private static final String DDL_SUFFIX = ".txt";
public DBInit(I2PAppContext ctx, Connection dbConn) {
_con = dbConn;
_log = ctx.logManager().getLog(DBInit.class);
}
/**
* Initialize the DB, update to latest version if necessary
*/
public void initDB() throws SQLException {
int version = checkDBVersion();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Known DB version: " + version);
if (version < 0) {
if (_log.shouldLog(Log.INFO))
_log.info("Building the database...");
}
int updates = getDBUpdateCount();
if (updates <= 0)
throw new SQLException("No DDL 0");
for (int i = version + 1; i < updates; i++) {
if (i >= version) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Updating database version " + i + " to " + (i+1));
updateDB(i);
}
}
}
private int checkDBVersion() {
PreparedStatement stmt = null;
try {
stmt = _con.prepareStatement("SELECT value FROM info WHERE key = 'version'");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
int rv = rs.getInt(1);
if (!rs.wasNull())
return rv;
}
return -1;
} catch (SQLException se) {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to check the database version (does not exist?)", se);
return -1;
} finally {
if (stmt != null) try { stmt.close(); } catch (SQLException se) {}
}
}
private int getDBUpdateCount() {
int updates = 0;
while (true) {
InputStream in = getClass().getResourceAsStream(DDL_PREFIX + updates + DDL_SUFFIX);
if (in != null) {
updates++;
try { in.close(); } catch (IOException ioe) {}
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("There were " + updates + " database updates known");
return updates;
}
}
}
/**
* Create a new DB with the version 1 ddl_update0.txt, or
* Update from oldVersion to oldVersion + 1 using ddl_update{oldVersion}.txt
*/
private void updateDB(int oldVersion) throws SQLException {
StringBuilder cmdBuf = new StringBuilder();
BufferedReader r = null;
try {
InputStream in = getClass().getResourceAsStream(DDL_PREFIX + oldVersion + DDL_SUFFIX);
if (in != null) {
r = new BufferedReader(new InputStreamReader(in));
String line = null;
while ( (line = r.readLine()) != null) {
line = line.trim();
if (line.startsWith("//") || line.startsWith("--"))
continue;
cmdBuf.append(' ').append(line);
if (line.endsWith(";")) {
exec(cmdBuf.toString());
cmdBuf.setLength(0);
}
}
r.close();
r = null;
} else {
throw new SQLException("Cannot load update for database version " + oldVersion);
}
} catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error reading the db script", ioe);
throw new SQLException(ioe.toString());
} catch (SQLException se) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error building the db, failed on statement: " + cmdBuf, se);
throw se;
} finally {
if (r != null) try { r.close(); } catch (IOException ioe) {}
}
}
private void exec(String cmd) throws SQLException {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Exec [" + cmd + "]");
PreparedStatement stmt = null;
try {
stmt = _con.prepareStatement(cmd);
stmt.execute();
} finally {
if (stmt != null) stmt.close();
}
}
}

File diff suppressed because it is too large Load Diff