001: /*
002: * This file or a portion of this file is licensed under the terms of
003: * the Globus Toolkit Public License, found in file ../GTPL, or at
004: * http://www.globus.org/toolkit/download/license.html. This notice must
005: * appear in redistributions of this file, with or without modification.
006: *
007: * Redistributions of this Software, with or without modification, must
008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009: * some other similar material which is provided with the Software (if
010: * any).
011: *
012: * Copyright 1999-2004 University of Chicago and The University of
013: * Southern California. All rights reserved.
014: */
015: package org.griphyn.vdl.dbdriver;
016:
017: import org.griphyn.vdl.dbdriver.DatabaseDriver;
018: import java.sql.*;
019: import java.util.*;
020: import org.griphyn.vdl.util.*;
021:
022: /**
023: * This class implements the driver API for the free, small, and fast
024: * file-based SQL Lite. This class is currently an empty non-working
025: * stand-in. Refer to the <a href="http://www.sqlite.org/">SQLite</a>
026: * site for details. We will fill this stand-in with life at some
027: * later time.<p>
028: *
029: * In order to use the SQLite driver, you must install the SQLite
030: * software first. Additionally, it is necessary to install the
031: * Java SQLite wrapper, which comes in two part. The JAR file is
032: * included with the VDS distribution. However, it is also necessary
033: * to either install the shared JNI library into your Java runtime, or
034: * point your LD_LIBRARY_PATH to the shared library.<p>
035: *
036: * @author Jens-S. Vöckler
037: * @author Yong Zhao
038: * @version $Revision: 50 $
039: *
040: * @see DatabaseDriver
041: * @see org.griphyn.vdl.dbschema
042: */
043: public class SQLite extends DatabaseDriver {
044: /**
045: * Default constructor. As the constructor will do nothing, please use
046: * the connect method to obtain a database connection.
047: *
048: * @see #connect( String, Properties, Set )
049: */
050: public SQLite() {
051: super ();
052: }
053:
054: /**
055: * Establish a connection to your database. The parameters will often
056: * be ignored or abused for different purposes on different backends.
057: * It is assumed that the connection is not in auto-commit mode, and
058: * explicit commits must be issued.
059: *
060: * @param url the contact string to database, or schema location
061: * @param info additional parameters, usually username and password
062: * @param tables is a set of all table names in the schema. The
063: * existence of all tables will be checked to verify
064: * that the schema is active in the database.
065: * @return true if the connection succeeded, false otherwise. Usually,
066: * false is returned, if the any of the tables or sequences is missing.
067: * @exception if the driver is incapable of establishing a connection.
068: */
069: public boolean connect(String url, Properties info, Set tables)
070: throws SQLException, ClassNotFoundException {
071: // load JDBC driver class into memory
072: return this .connect("SQLite.JDBCDriver", url, info, tables);
073: }
074:
075: /**
076: * Determines, if the backend is expensive, and results should be cached.
077: * Ideally, this will move transparently into the backend itself.
078: * @return true if caching is advisable, false for no caching.
079: */
080: public boolean cachingMakesSense() {
081: return true;
082: }
083:
084: /**
085: * Quotes a string that may contain special SQL characters.
086: * @param s is the raw string.
087: * @return the quoted string, which may be just the input string.
088: */
089: public String quote(String s) {
090: if (s.indexOf('\'') != -1) {
091: StringBuffer result = new StringBuffer();
092: for (int i = 0; i < s.length(); ++i) {
093: char ch = s.charAt(i);
094: result.append(ch);
095: if (ch == '\'')
096: result.append(ch);
097: }
098: return result.toString();
099: } else {
100: return s;
101: }
102: }
103:
104: /**
105: * Obtains the next value from a sequence. SQLite prefers NULL-driven
106: * auto-increment columns, so this function will always return -1.
107: *
108: * @param name is the name of the sequence.
109: * @return the next sequence number.
110: * @exception if something goes wrong while fetching the new value.
111: */
112: public long sequence1(String name) throws SQLException {
113: return -1;
114: }
115:
116: /**
117: * Obtains the sequence value for the current statement. SQLite uses
118: * NULL-driven auto-increment column. Thus, we do the heavy lifting
119: * here.
120: *
121: * @param s is a statment or prepared statement
122: * @param name is the name of the sequence.
123: * @param pos is the column number of the auto-increment column.
124: * @return the next sequence number.
125: * @exception if something goes wrong while fetching the new value.
126: */
127: public long sequence2(Statement s, String name, int pos)
128: throws SQLException {
129: long result = -1;
130:
131: Logging.instance()
132: .log("sql", 2, "SELECT nextval(" + name + ")");
133: Logging.instance().log("xaction", 1, "START sequence " + name);
134:
135: // obtain last inserted value
136: ResultSet rs = s.getGeneratedKeys();
137: if (rs.next()) {
138: result = rs.getLong(pos);
139: } else {
140: throw new SQLException("no auto-increment");
141: }
142: rs.close();
143:
144: // done
145: Logging.instance().log("xaction", 1,
146: "FINAL sequence " + name + " = " + result);
147: return result;
148: }
149:
150: /**
151: * Predicate to tell the schema, if using a string instead of number
152: * will result in the speedier index scans instead of sequential scans.
153: * PostGreSQL has this problem, but using strings in the place of
154: * integers may not be universally portable.
155: *
156: * @return true, if using strings instead of integers and bigints
157: * will yield better performance.
158: *
159: */
160: public boolean preferString() {
161: return false;
162: }
163: }
|