Changeset 3181 for XerialJ/trunk/sqlite-jdbc
- Timestamp:
- 04/08/09 19:12:24 (3 years ago)
- Location:
- XerialJ/trunk/sqlite-jdbc
- Files:
-
- 1 added
- 10 modified
-
Makefile (modified) (1 diff)
-
sqlitejdbc/Makefile (modified) (1 diff)
-
sqlitejdbc/Makefile.nested (modified) (1 diff)
-
src/main/java/org/sqlite/Conn.java (modified) (2 diffs)
-
src/main/java/org/sqlite/DB.java (modified) (1 diff)
-
src/main/java/org/sqlite/JDBC.java (modified) (3 diffs)
-
src/main/java/org/sqlite/NativeDB.c (modified) (1 diff)
-
src/main/java/org/sqlite/NativeDB.java (modified) (2 diffs)
-
src/main/java/org/sqlite/NestedDB.java (modified) (12 diffs)
-
src/main/resources/native/Windows/x86/sqlitejdbc.dll (modified) (previous)
-
src/test/java/org/sqlite/JDBCTest.java (added)
Legend:
- Unmodified
- Added
- Removed
-
XerialJ/trunk/sqlite-jdbc/Makefile
r2855 r3181 47 47 SQLITE_BUILD_DIR=sqlitejdbc/build/$(sqlite)-$(target) 48 48 49 LIB_FOLDER = $(shell java -cp target/sqlitejdbc org.xerial.db.sql.sqlite.OSInfo)49 LIB_FOLDER = $(shell java -cp target/sqlitejdbc $(OSInfoClass)) 50 50 WORK_DIR=target/dll/$(sqlite)/native 51 51 UPDATE_FLAG=target/dll/$(sqlite)/UPDATE -
XerialJ/trunk/sqlite-jdbc/sqlitejdbc/Makefile
r2855 r3181 52 52 -DSQLITE_ENABLE_FTS3 \ 53 53 -DSQLITE_ENABLE_RTREE \ 54 -DSQLITE_OMIT_LOAD_EXTENSIONsqlite3.c)54 sqlite3.c) 55 55 56 56 build/org/sqlite/%.class: ../src/main/java/org/sqlite/%.java -
XerialJ/trunk/sqlite-jdbc/sqlitejdbc/Makefile.nested
r2855 r3181 64 64 -DSQLITE_ENABLE_FTS3 \ 65 65 -DSQLITE_ENABLE_RTREE \ 66 -DSQLITE_OMIT_LOAD_EXTENSION \67 66 sqlite3.c; \ 68 67 $$CC -c $$CFLAGS -o NestedDB.o Nested*.c) -
XerialJ/trunk/sqlite-jdbc/src/main/java/org/sqlite/Conn.java
r2847 r3181 28 28 import java.sql.Struct; 29 29 import java.util.Map; 30 import java.util.Properties; 30 31 31 32 class Conn implements Connection … … 38 39 private int timeout = 0; 39 40 40 public Conn(String url, String filename, boolean sharedCache) throws SQLException41 public Conn(String url, String filename, Properties prop) throws SQLException 41 42 { 42 43 this(url, filename); 43 db.shared_cache(sharedCache); 44 45 boolean enableSharedCache = Boolean.parseBoolean(prop.getProperty("shared_cache", "false")); 46 boolean enableLoadExtension = Boolean.parseBoolean(prop.getProperty("enable_load_extension", "false")); 47 48 db.shared_cache(enableSharedCache); 49 db.enable_load_extension(enableLoadExtension); 44 50 } 45 51 -
XerialJ/trunk/sqlite-jdbc/src/main/java/org/sqlite/DB.java
r2990 r3181 61 61 abstract int shared_cache(boolean enable) throws SQLException; 62 62 63 abstract int enable_load_extension(boolean enable) throws SQLException; 64 63 65 final synchronized void exec(String sql) throws SQLException 64 66 { -
XerialJ/trunk/sqlite-jdbc/src/main/java/org/sqlite/JDBC.java
r2254 r3181 17 17 package org.sqlite; 18 18 19 import java.sql.*; 20 import java.util.*; 19 import java.sql.Connection; 20 import java.sql.Driver; 21 import java.sql.DriverManager; 22 import java.sql.DriverPropertyInfo; 23 import java.sql.SQLException; 24 import java.util.Properties; 21 25 22 26 public class JDBC implements Driver … … 24 28 private static final String PREFIX = "jdbc:sqlite:"; 25 29 26 static { 27 try { 30 static 31 { 32 try 33 { 28 34 DriverManager.registerDriver(new JDBC()); 29 } catch (SQLException e) { 35 } 36 catch (SQLException e) 37 { 30 38 e.printStackTrace(); 31 39 } 32 40 } 33 41 34 public int getMajorVersion() { return 1; } 35 public int getMinorVersion() { return 1; } 42 public int getMajorVersion() 43 { 44 return 1; 45 } 36 46 37 public boolean jdbcCompliant() { return false; } 47 public int getMinorVersion() 48 { 49 return 1; 50 } 38 51 39 public boolean acceptsURL(String url) { 52 public boolean jdbcCompliant() 53 { 54 return false; 55 } 56 57 public boolean acceptsURL(String url) 58 { 40 59 return url != null && url.toLowerCase().startsWith(PREFIX); 41 60 } 42 61 43 public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) 44 throws SQLException { 45 DriverPropertyInfo sharedCache = new DriverPropertyInfo( 46 "shared_cache", "false"); 62 public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException 63 { 64 DriverPropertyInfo sharedCache = new DriverPropertyInfo("shared_cache", "false"); 47 65 sharedCache.choices = new String[] { "true", "false" }; 48 sharedCache.description = 49 "Enable SQLite Shared-Cache mode, native driver only."; 66 sharedCache.description = "Enable SQLite Shared-Cache mode, native driver only."; 50 67 sharedCache.required = false; 51 68 … … 53 70 } 54 71 55 public Connection connect(String url, Properties info) throws SQLException { 56 if (!acceptsURL(url)) return null; 72 public Connection connect(String url, Properties info) throws SQLException 73 { 74 if (!acceptsURL(url)) 75 return null; 57 76 url = url.trim(); 58 77 59 78 // if no file name is given use a memory database 60 String file = PREFIX.equalsIgnoreCase(url) ? 61 ":memory:" : url.substring(PREFIX.length()); 79 String file = PREFIX.equalsIgnoreCase(url) ? ":memory:" : url.substring(PREFIX.length()); 62 80 63 if (info.getProperty("shared_cache") == null) 64 return new Conn(url, file); 65 else 66 return new Conn(url, file, 67 Boolean.parseBoolean(info.getProperty("shared_cache"))); 81 return new Conn(url, file, info); 68 82 } 69 83 } -
XerialJ/trunk/sqlite-jdbc/src/main/java/org/sqlite/NativeDB.c
r2254 r3181 289 289 } 290 290 291 292 JNIEXPORT jint JNICALL Java_org_sqlite_NativeDB_enable_1load_1extension( 293 JNIEnv *env, jobject this, jboolean enable) 294 { 295 return sqlite3_enable_load_extension(gethandle(env, this), enable ? 1 : 0); 296 } 297 298 291 299 JNIEXPORT void JNICALL Java_org_sqlite_NativeDB__1open( 292 300 JNIEnv *env, jobject this, jstring file) -
XerialJ/trunk/sqlite-jdbc/src/main/java/org/sqlite/NativeDB.java
r2852 r3181 36 36 isLoaded = true; 37 37 return loadSucceeded; 38 39 // String libpath = System.getProperty("org.sqlite.lib.path");40 // String libname = System.getProperty("org.sqlite.lib.name");41 // if (libname == null) libname = System.mapLibraryName("sqlitejdbc");42 //43 // // look for a pre-installed library44 // try {45 // if (libpath == null) System.loadLibrary("sqlitejdbc");46 // else System.load(new File(libpath, libname).getAbsolutePath());47 //48 // loaded = Boolean.TRUE;49 // return true;50 // } catch (UnsatisfiedLinkError e) { } // fall through51 //52 // // guess what a bundled library would be called53 // String osname = System.getProperty("os.name").toLowerCase();54 // String osarch = System.getProperty("os.arch");55 // if (osname.startsWith("mac os")) {56 // osname = "mac";57 // osarch = "universal";58 // }59 // if (osname.startsWith("windows"))60 // osname = "win";61 // if (osname.startsWith("sunos"))62 // osname = "solaris";63 // if (osarch.startsWith("i") && osarch.endsWith("86"))64 // osarch = "x86";65 // libname = osname + '-' + osarch + ".lib";66 //67 // // try a bundled library68 // try {69 // ClassLoader cl = NativeDB.class.getClassLoader();70 // InputStream in = cl.getResourceAsStream(libname);71 // if (in == null)72 // throw new Exception("libname: "+libname+" not found");73 // File tmplib = File.createTempFile("libsqlitejdbc-", ".lib");74 // tmplib.deleteOnExit();75 // OutputStream out = new FileOutputStream(tmplib);76 // byte[] buf = new byte[1024];77 // for (int len; (len = in.read(buf)) != -1;)78 // out.write(buf, 0, len);79 // in.close();80 // out.close();81 //82 // System.load(tmplib.getAbsolutePath());83 //84 // loaded = Boolean.TRUE;85 // return true;86 // } catch (Exception e) { }87 //88 // loaded = Boolean.FALSE;89 // return false;90 38 } 91 39 … … 100 48 101 49 native synchronized int shared_cache(boolean enable); 50 51 native synchronized int enable_load_extension(boolean enable); 102 52 103 53 native synchronized void interrupt(); -
XerialJ/trunk/sqlite-jdbc/src/main/java/org/sqlite/NestedDB.java
r2253 r3181 16 16 package org.sqlite; 17 17 18 import java.io.PrintWriter; 19 import java.sql.SQLException; 20 18 21 import org.ibex.nestedvm.Runtime; 19 20 import java.io.File;21 import java.io.PrintWriter;22 import java.sql.*;23 22 24 23 // FEATURE: strdup is wasteful, SQLite interface will take unterminated char* … … 35 34 /** user defined functions referenced by position (stored in used data) */ 36 35 private Function[] functions = null; 37 private String[] funcNames = null; 38 36 private String[] funcNames = null; 39 37 40 38 // WRAPPER FUNCTIONS //////////////////////////////////////////// 41 39 42 protected synchronized void _open(String filename) throws SQLException { 43 if (handle != 0) throw new SQLException("DB already open"); 40 protected synchronized void _open(String filename) throws SQLException 41 { 42 if (handle != 0) 43 throw new SQLException("DB already open"); 44 44 45 45 // handle silly windows drive letter mapping 46 if (filename.length() > 2) { 46 if (filename.length() > 2) 47 { 47 48 char drive = Character.toLowerCase(filename.charAt(0)); 48 if (filename.charAt(1) == ':' && drive >= 'a' && drive <= 'z') { 49 if (filename.charAt(1) == ':' && drive >= 'a' && drive <= 'z') 50 { 49 51 50 52 // convert to nestedvm's "/c:/file" format … … 56 58 57 59 // start the nestedvm runtime 58 try {59 rt = (Runtime)Class.forName("org.sqlite.SQLite")60 .newInstance();60 try 61 { 62 rt = (Runtime) Class.forName("org.sqlite.SQLite").newInstance(); 61 63 rt.start(); 62 } catch (Exception e) { 64 } 65 catch (Exception e) 66 { 63 67 throw new CausedSQLException(e); 64 68 } … … 78 82 79 83 /* callback for Runtime.CallJavaCB above */ 80 public int call(int xType, int context, int args, int value) { 84 public int call(int xType, int context, int args, int value) 85 { 81 86 xUDF(xType, context, args, value); 82 87 return 0; 83 88 } 84 89 85 protected synchronized void _close() throws SQLException { 86 if (handle == 0) return; 87 try { 90 protected synchronized void _close() throws SQLException 91 { 92 if (handle == 0) 93 return; 94 try 95 { 88 96 if (call("sqlite3_close", handle) != SQLITE_OK) 89 97 throwex(); 90 } finally { 98 } 99 finally 100 { 91 101 handle = 0; 92 102 rt.stop(); … … 95 105 } 96 106 97 int shared_cache(boolean enable) throws SQLException { 107 int shared_cache(boolean enable) throws SQLException 108 { 98 109 // The shared cache is per-process, so it is useless as 99 110 // each nested connection is its own process. 100 111 return -1; 101 112 } 102 synchronized void interrupt() throws SQLException { 113 114 int enable_load_extension(boolean enable) throws SQLException 115 { 116 return call("sqlite3_enable_load_extension", handle, enable ? 1 : 0); 117 } 118 119 synchronized void interrupt() throws SQLException 120 { 103 121 call("sqlite3_interrupt", handle); 104 122 } 105 synchronized void busy_timeout(int ms) throws SQLException { 123 124 synchronized void busy_timeout(int ms) throws SQLException 125 { 106 126 call("sqlite3_busy_timeout", handle, ms); 107 127 } 108 protected synchronized long prepare(String sql) throws SQLException { 128 129 protected synchronized long prepare(String sql) throws SQLException 130 { 109 131 int passback = rt.xmalloc(4); 110 132 int str = rt.strdup(sql); 111 133 int ret = call("sqlite3_prepare_v2", handle, str, -1, passback, 0); 112 134 rt.free(str); 113 if (ret != SQLITE_OK) { 135 if (ret != SQLITE_OK) 136 { 114 137 rt.free(passback); 115 138 throwex(); … … 119 142 return pointer; 120 143 } 121 synchronized String errmsg() throws SQLException { 144 145 synchronized String errmsg() throws SQLException 146 { 122 147 return cstring(call("sqlite3_errmsg", handle)); 123 148 } 124 synchronized String libversion() throws SQLException { 149 150 synchronized String libversion() throws SQLException 151 { 125 152 return cstring(call("sqlite3_libversion", handle)); 126 153 } 127 synchronized int changes() throws SQLException { 128 return call("sqlite3_changes", handle); } 129 130 protected synchronized int finalize(long stmt) throws SQLException { 131 return call("sqlite3_finalize", (int)stmt); } 132 protected synchronized int step(long stmt) throws SQLException { 133 return call("sqlite3_step", (int)stmt); } 134 protected synchronized int reset(long stmt) throws SQLException { 135 return call("sqlite3_reset", (int)stmt); } 136 synchronized int clear_bindings(long stmt) throws SQLException { 137 return call("sqlite3_clear_bindings", (int)stmt); } 138 139 synchronized int bind_parameter_count(long stmt) throws SQLException { 140 return call("sqlite3_bind_parameter_count", (int)stmt); } 141 142 synchronized int column_count(long stmt) throws SQLException { 143 return call("sqlite3_column_count", (int)stmt); } 144 synchronized int column_type(long stmt, int col) throws SQLException { 145 return call("sqlite3_column_type", (int)stmt, col); } 146 synchronized String column_name(long stmt, int col) throws SQLException { 147 return utfstring(call("sqlite3_column_name", (int)stmt, col)); 148 } 149 synchronized String column_text(long stmt, int col) throws SQLException { 150 return utfstring(call("sqlite3_column_text", (int)stmt, col)); 151 } 152 synchronized byte[] column_blob(long stmt, int col) throws SQLException { 153 int addr = call("sqlite3_column_blob", (int)stmt, col); 154 if (addr == 0) return null; 155 byte[] blob = new byte[call("sqlite3_column_bytes", (int)stmt, col)]; 154 155 synchronized int changes() throws SQLException 156 { 157 return call("sqlite3_changes", handle); 158 } 159 160 protected synchronized int finalize(long stmt) throws SQLException 161 { 162 return call("sqlite3_finalize", (int) stmt); 163 } 164 165 protected synchronized int step(long stmt) throws SQLException 166 { 167 return call("sqlite3_step", (int) stmt); 168 } 169 170 protected synchronized int reset(long stmt) throws SQLException 171 { 172 return call("sqlite3_reset", (int) stmt); 173 } 174 175 synchronized int clear_bindings(long stmt) throws SQLException 176 { 177 return call("sqlite3_clear_bindings", (int) stmt); 178 } 179 180 synchronized int bind_parameter_count(long stmt) throws SQLException 181 { 182 return call("sqlite3_bind_parameter_count", (int) stmt); 183 } 184 185 synchronized int column_count(long stmt) throws SQLException 186 { 187 return call("sqlite3_column_count", (int) stmt); 188 } 189 190 synchronized int column_type(long stmt, int col) throws SQLException 191 { 192 return call("sqlite3_column_type", (int) stmt, col); 193 } 194 195 synchronized String column_name(long stmt, int col) throws SQLException 196 { 197 return utfstring(call("sqlite3_column_name", (int) stmt, col)); 198 } 199 200 synchronized String column_text(long stmt, int col) throws SQLException 201 { 202 return utfstring(call("sqlite3_column_text", (int) stmt, col)); 203 } 204 205 synchronized byte[] column_blob(long stmt, int col) throws SQLException 206 { 207 int addr = call("sqlite3_column_blob", (int) stmt, col); 208 if (addr == 0) 209 return null; 210 byte[] blob = new byte[call("sqlite3_column_bytes", (int) stmt, col)]; 156 211 copyin(addr, blob, blob.length); 157 212 return blob; 158 213 } 159 synchronized double column_double(long stmt, int col) throws SQLException { 160 try { return Double.parseDouble(column_text(stmt, col)); } 161 catch (NumberFormatException e) { return Double.NaN; } // TODO 162 } 163 synchronized long column_long(long stmt, int col) throws SQLException { 164 try { return Long.parseLong(column_text(stmt, col)); } 165 catch (NumberFormatException e) { return 0; } // TODO 166 } 167 synchronized int column_int(long stmt, int col) throws SQLException { 168 return call("sqlite3_column_int", (int)stmt, col); } 169 synchronized String column_decltype(long stmt, int col) 170 throws SQLException { 171 return utfstring(call("sqlite3_column_decltype", (int)stmt, col)); 172 } 173 synchronized String column_table_name(long stmt, int col) 174 throws SQLException { 175 return utfstring(call("sqlite3_column_table_name", (int)stmt, col)); 176 } 177 178 synchronized int bind_null(long stmt, int pos) throws SQLException { 179 return call("sqlite3_bind_null", (int)stmt, pos); 180 } 181 synchronized int bind_int(long stmt, int pos, int v) throws SQLException { 182 return call("sqlite3_bind_int", (int)stmt, pos, v); 183 } 184 synchronized int bind_long(long stmt, int pos, long v) throws SQLException { 185 return bind_text(stmt, pos, Long.toString(v)); // TODO 186 } 187 synchronized int bind_double(long stmt, int pos, double v) 188 throws SQLException { 189 return bind_text(stmt, pos, Double.toString(v)); // TODO 190 } 191 synchronized int bind_text(long stmt, int pos, String v) 192 throws SQLException { 193 if (v == null) return bind_null(stmt, pos); 194 return call("sqlite3_bind_text", (int)stmt, pos, rt.strdup(v), 195 -1, rt.lookupSymbol("free")); 196 } 197 synchronized int bind_blob(long stmt, int pos, byte[] buf) 198 throws SQLException { 199 if (buf == null || buf.length < 1) return bind_null(stmt, pos); 214 215 synchronized double column_double(long stmt, int col) throws SQLException 216 { 217 try 218 { 219 return Double.parseDouble(column_text(stmt, col)); 220 } 221 catch (NumberFormatException e) 222 { 223 return Double.NaN; 224 } // TODO 225 } 226 227 synchronized long column_long(long stmt, int col) throws SQLException 228 { 229 try 230 { 231 return Long.parseLong(column_text(stmt, col)); 232 } 233 catch (NumberFormatException e) 234 { 235 return 0; 236 } // TODO 237 } 238 239 synchronized int column_int(long stmt, int col) throws SQLException 240 { 241 return call("sqlite3_column_int", (int) stmt, col); 242 } 243 244 synchronized String column_decltype(long stmt, int col) throws SQLException 245 { 246 return utfstring(call("sqlite3_column_decltype", (int) stmt, col)); 247 } 248 249 synchronized String column_table_name(long stmt, int col) throws SQLException 250 { 251 return utfstring(call("sqlite3_column_table_name", (int) stmt, col)); 252 } 253 254 synchronized int bind_null(long stmt, int pos) throws SQLException 255 { 256 return call("sqlite3_bind_null", (int) stmt, pos); 257 } 258 259 synchronized int bind_int(long stmt, int pos, int v) throws SQLException 260 { 261 return call("sqlite3_bind_int", (int) stmt, pos, v); 262 } 263 264 synchronized int bind_long(long stmt, int pos, long v) throws SQLException 265 { 266 return bind_text(stmt, pos, Long.toString(v)); // TODO 267 } 268 269 synchronized int bind_double(long stmt, int pos, double v) throws SQLException 270 { 271 return bind_text(stmt, pos, Double.toString(v)); // TODO 272 } 273 274 synchronized int bind_text(long stmt, int pos, String v) throws SQLException 275 { 276 if (v == null) 277 return bind_null(stmt, pos); 278 return call("sqlite3_bind_text", (int) stmt, pos, rt.strdup(v), -1, rt.lookupSymbol("free")); 279 } 280 281 synchronized int bind_blob(long stmt, int pos, byte[] buf) throws SQLException 282 { 283 if (buf == null || buf.length < 1) 284 return bind_null(stmt, pos); 200 285 int len = buf.length; 201 286 int blob = rt.xmalloc(len); // free()ed by sqlite3_bind_blob 202 287 copyout(buf, blob, len); 203 return call("sqlite3_bind_blob", (int)stmt, pos, blob, len, 204 rt.lookupSymbol("free")); 205 } 206 207 synchronized void result_null(long cxt) throws SQLException { 208 call("sqlite3_result_null", (int)cxt); } 209 synchronized void result_text(long cxt, String val) throws SQLException { 210 call("sqlite3_result_text", (int)cxt, rt.strdup(val), -1, 211 rt.lookupSymbol("free")); 212 } 213 synchronized void result_blob(long cxt, byte[] val) throws SQLException { 214 if (val == null || val.length == 0) { result_null(cxt); return; } 288 return call("sqlite3_bind_blob", (int) stmt, pos, blob, len, rt.lookupSymbol("free")); 289 } 290 291 synchronized void result_null(long cxt) throws SQLException 292 { 293 call("sqlite3_result_null", (int) cxt); 294 } 295 296 synchronized void result_text(long cxt, String val) throws SQLException 297 { 298 call("sqlite3_result_text", (int) cxt, rt.strdup(val), -1, rt.lookupSymbol("free")); 299 } 300 301 synchronized void result_blob(long cxt, byte[] val) throws SQLException 302 { 303 if (val == null || val.length == 0) 304 { 305 result_null(cxt); 306 return; 307 } 215 308 int blob = rt.xmalloc(val.length); 216 309 copyout(val, blob, val.length); 217 call("sqlite3_result_blob", (int)cxt, blob, 218 val.length, rt.lookupSymbol("free")); 219 } 220 synchronized void result_double(long cxt, double val) throws SQLException { 221 result_text(cxt, Double.toString(val)); } // TODO 222 synchronized void result_long(long cxt, long val) throws SQLException { 223 result_text(cxt, Long.toString(val)); } // TODO 224 synchronized void result_int(long cxt, int val) throws SQLException { 225 call("sqlite3_result_int", (int)cxt, val); } 226 synchronized void result_error(long cxt, String err) throws SQLException { 310 call("sqlite3_result_blob", (int) cxt, blob, val.length, rt.lookupSymbol("free")); 311 } 312 313 synchronized void result_double(long cxt, double val) throws SQLException 314 { 315 result_text(cxt, Double.toString(val)); 316 } // TODO 317 318 synchronized void result_long(long cxt, long val) throws SQLException 319 { 320 result_text(cxt, Long.toString(val)); 321 } // TODO 322 323 synchronized void result_int(long cxt, int val) throws SQLException 324 { 325 call("sqlite3_result_int", (int) cxt, val); 326 } 327 328 synchronized void result_error(long cxt, String err) throws SQLException 329 { 227 330 int str = rt.strdup(err); 228 call("sqlite3_result_error", (int) cxt, str, -1);331 call("sqlite3_result_error", (int) cxt, str, -1); 229 332 rt.free(str); 230 333 } 231 334 232 synchronized int value_bytes(Function f, int arg) throws SQLException { 335 synchronized int value_bytes(Function f, int arg) throws SQLException 336 { 233 337 return call("sqlite3_value_bytes", value(f, arg)); 234 338 } 235 synchronized String value_text(Function f, int arg) throws SQLException { 339 340 synchronized String value_text(Function f, int arg) throws SQLException 341 { 236 342 return utfstring(call("sqlite3_value_text", value(f, arg))); 237 343 } 238 synchronized byte[] value_blob(Function f, int arg) throws SQLException { 344 345 synchronized byte[] value_blob(Function f, int arg) throws SQLException 346 { 239 347 int addr = call("sqlite3_value_blob", value(f, arg)); 240 if (addr == 0) return null; 348 if (addr == 0) 349 return null; 241 350 byte[] blob = new byte[value_bytes(f, arg)]; 242 351 copyin(addr, blob, blob.length); 243 352 return blob; 244 353 } 245 synchronized double value_double(Function f, int arg) throws SQLException { 354 355 synchronized double value_double(Function f, int arg) throws SQLException 356 { 246 357 return Double.parseDouble(value_text(f, arg)); // TODO 247 358 } 248 synchronized long value_long(Function f, int arg) throws SQLException { 359 360 synchronized long value_long(Function f, int arg) throws SQLException 361 { 249 362 return Long.parseLong(value_text(f, arg)); // TODO 250 363 } 251 synchronized int value_int(Function f, int arg) throws SQLException { 364 365 synchronized int value_int(Function f, int arg) throws SQLException 366 { 252 367 return call("sqlite3_value_int", value(f, arg)); 253 368 } 254 synchronized int value_type(Function f, int arg) throws SQLException { 369 370 synchronized int value_type(Function f, int arg) throws SQLException 371 { 255 372 return call("sqlite3_value_type", value(f, arg)); 256 373 } 257 374 258 private int value(Function f, int arg) throws SQLException { 259 return deref((int)f.value + (arg*4)); 260 } 261 262 263 synchronized int create_function(String name, Function func) 264 throws SQLException { 265 if (functions == null) { 375 private int value(Function f, int arg) throws SQLException 376 { 377 return deref((int) f.value + (arg * 4)); 378 } 379 380 synchronized int create_function(String name, Function func) throws SQLException 381 { 382 if (functions == null) 383 { 266 384 functions = new Function[10]; 267 385 funcNames = new String[10]; … … 270 388 // find a position 271 389 int pos; 272 for (pos=0; pos < functions.length; pos++) 273 if (functions[pos] == null) break; 274 275 if (pos == functions.length) { // expand function arrays 390 for (pos = 0; pos < functions.length; pos++) 391 if (functions[pos] == null) 392 break; 393 394 if (pos == functions.length) 395 { // expand function arrays 276 396 Function[] fnew = new Function[functions.length * 2]; 277 397 String[] nnew = new String[funcNames.length * 2]; … … 287 407 int rc; 288 408 int str = rt.strdup(name); 289 rc = call("create_function_helper", handle, str, pos, 290 func instanceof Function.Aggregate ? 1 : 0); 409 rc = call("create_function_helper", handle, str, pos, func instanceof Function.Aggregate ? 1 : 0); 291 410 rt.free(str); 292 411 return rc; 293 412 } 294 413 295 synchronized int destroy_function(String name) throws SQLException { 296 if (name == null) return 0; 414 synchronized int destroy_function(String name) throws SQLException 415 { 416 if (name == null) 417 return 0; 297 418 298 419 // find function position number 299 420 int pos; 300 421 for (pos = 0; pos < funcNames.length; pos++) 301 if (name.equals(funcNames[pos])) break; 302 if (pos == funcNames.length) return 0; 422 if (name.equals(funcNames[pos])) 423 break; 424 if (pos == funcNames.length) 425 return 0; 303 426 304 427 functions[pos] = null; … … 314 437 315 438 /* unused as we use the user_data pointer to store a single word */ 316 synchronized void free_functions() {} 439 synchronized void free_functions() 440 {} 317 441 318 442 /** Callback used by xFunc (1), xStep (2) and xFinal (3). */ 319 synchronized void xUDF(int xType, int context, int args, int value) { 443 synchronized void xUDF(int xType, int context, int args, int value) 444 { 320 445 Function func = null; 321 446 322 try { 447 try 448 { 323 449 int pos = call("sqlite3_user_data", context); 324 450 func = functions[pos]; … … 330 456 func.args = args; 331 457 332 switch (xType) { 333 case 1: func.xFunc(); break; 334 case 2: ((Function.Aggregate)func).xStep(); break; 335 case 3: ((Function.Aggregate)func).xFinal(); break; 458 switch (xType) 459 { 460 case 1: 461 func.xFunc(); 462 break; 463 case 2: 464 ((Function.Aggregate) func).xStep(); 465 break; 466 case 3: 467 ((Function.Aggregate) func).xFinal(); 468 break; 336 469 } 337 } catch (SQLException e) { 338 try { 470 } 471 catch (SQLException e) 472 { 473 try 474 { 339 475 String err = e.toString(); 340 if (err == null) err = "unknown error"; 476 if (err == null) 477 err = "unknown error"; 341 478 int str = rt.strdup(err); 342 479 call("sqlite3_result_error", context, str, -1); 343 480 rt.free(str); 344 } catch (SQLException exp) { 481 } 482 catch (SQLException exp) 483 { 345 484 exp.printStackTrace();//TODO 346 485 } 347 } finally { 348 if (func != null) { 486 } 487 finally 488 { 489 if (func != null) 490 { 349 491 func.context = 0; 350 492 func.value = 0; … … 354 496 } 355 497 356 357 498 /** Calls support function found in upstream/sqlite-metadata.patch */ 358 synchronized boolean[][] column_metadata(long stmt) throws SQLException { 359 int colCount = call("sqlite3_column_count", (int)stmt); 499 synchronized boolean[][] column_metadata(long stmt) throws SQLException 500 { 501 int colCount = call("sqlite3_column_count", (int) stmt); 360 502 boolean[][] meta = new boolean[colCount][3]; 361 503 int pass; 362 504 363 505 pass = rt.xmalloc(12); // struct metadata 364 506 365 for (int i=0; i < colCount; i++) { 366 call("column_metadata_helper", handle, (int)stmt, i, pass); 507 for (int i = 0; i < colCount; i++) 508 { 509 call("column_metadata_helper", handle, (int) stmt, i, pass); 367 510 meta[i][0] = deref(pass) == 1; 368 511 meta[i][1] = deref(pass + 4) == 1; … … 374 517 } 375 518 376 377 519 // HELPER FUNCTIONS ///////////////////////////////////////////// 378 520 379 521 /** safe to reuse parameter arrays as all functions are syncrhonized */ 380 private final int[] 381 p0 = new int[] {}, 382 p1 = new int[] { 0 }, 383 p2 = new int[] { 0, 0 }, 384 p3 = new int[] { 0, 0, 0 }, 385 p4 = new int[] { 0, 0, 0, 0 }, 386 p5 = new int[] { 0, 0, 0, 0, 0 }; 387 388 private int call(String addr, int a0) throws SQLException { 389 p1[0] = a0; return call(addr, p1); } 390 private int call(String addr, int a0, int a1) throws SQLException { 391 p2[0] = a0; p2[1] = a1; return call(addr, p2); } 392 private int call(String addr, int a0, int a1, int a2) throws SQLException { 393 p3[0] = a0; p3[1] = a1; p3[2] = a2; return call(addr, p3); } 394 private int call(String addr, int a0, int a1, int a2, int a3) 395 throws SQLException { 396 p4[0] = a0; p4[1] = a1; p4[2] = a2; p4[3] = a3; 522 private final int[] p0 = new int[] {}, p1 = new int[] { 0 }, p2 = new int[] { 0, 0 }, p3 = new int[] { 0, 0, 0 }, 523 p4 = new int[] { 0, 0, 0, 0 }, p5 = new int[] { 0, 0, 0, 0, 0 }; 524 525 private int call(String addr, int a0) throws SQLException 526 { 527 p1[0] = a0; 528 return call(addr, p1); 529 } 530 531 private int call(String addr, int a0, int a1) throws SQLException 532 { 533 p2[0] = a0; 534 p2[1] = a1; 535 return call(addr, p2); 536 } 537 538 private int call(String addr, int a0, int a1, int a2) throws SQLException 539 { 540 p3[0] = a0; 541 p3[1] = a1; 542 p3[2] = a2; 543 return call(addr, p3); 544 } 545 546 private int call(String addr, int a0, int a1, int a2, int a3) throws SQLException 547 { 548 p4[0] = a0; 549 p4[1] = a1; 550 p4[2] = a2; 551 p4[3] = a3; 397 552 return call(addr, p4); 398 553 } 399 private int call(String addr, int a0, int a1, int a2, int a3, int a4) 400 throws SQLException { 401 p5[0] = a0; p5[1] = a1; p5[2] = a2; p5[3] = a3; p5[4] = a4; 554 555 private int call(String addr, int a0, int a1, int a2, int a3, int a4) throws SQLException 556 { 557 p5[0] = a0; 558 p5[1] = a1; 559 p5[2] = a2; 560 p5[3] = a3; 561 p5[4] = a4; 402 562 return call(addr, p5); 403 563 } 404 private int call(String func, int[] args) throws SQLException { 405 try { 564 565 private int call(String func, int[] args) throws SQLException 566 { 567 try 568 { 406 569 return rt.call(func, args); 407 } catch (Runtime.CallException e) { throw new CausedSQLException(e); } 570 } 571 catch (Runtime.CallException e) 572 { 573 throw new CausedSQLException(e); 574 } 408 575 } 409 576 410 577 /** Dereferences a pointer, returning the word it points to. */ 411 private int deref(int pointer) throws SQLException { 412 try { return rt.memRead(pointer); } 413 catch (Runtime.ReadFaultException e) { throw new CausedSQLException(e);} 414 } 415 private String utfstring(int str) throws SQLException { 416 try { return rt.utfstring(str); } 417 catch (Runtime.ReadFaultException e) { throw new CausedSQLException(e);} 418 } 419 private String cstring(int str) throws SQLException { 420 try { return rt.cstring(str); } 421 catch (Runtime.ReadFaultException e) { throw new CausedSQLException(e);} 422 } 423 private void copyin(int addr, byte[] buf, int count) throws SQLException { 424 try { rt.copyin(addr, buf, count); } 425 catch (Runtime.ReadFaultException e) { throw new CausedSQLException(e);} 426 } 427 private void copyout(byte[] buf, int addr, int count) throws SQLException { 428 try { rt.copyout(buf, addr, count); } 429 catch (Runtime.FaultException e) { throw new CausedSQLException(e);} 578 private int deref(int pointer) throws SQLException 579 { 580 try 581 { 582 return rt.memRead(pointer); 583 } 584 catch (Runtime.ReadFaultException e) 585 { 586 throw new CausedSQLException(e); 587 } 588 } 589 590 private String utfstring(int str) throws SQLException 591 { 592 try 593 { 594 return rt.utfstring(str); 595 } 596 catch (Runtime.ReadFaultException e) 597 { 598 throw new CausedSQLException(e); 599 } 600 } 601 602 private String cstring(int str) throws SQLException 603 { 604 try 605 { 606 return rt.cstring(str); 607 } 608 catch (Runtime.ReadFaultException e) 609 { 610 throw new CausedSQLException(e); 611 } 612 } 613 614 private void copyin(int addr, byte[] buf, int count) throws SQLException 615 { 616 try 617 { 618 rt.copyin(addr, buf, count); 619 } 620 catch (Runtime.ReadFaultException e) 621 { 622 throw new CausedSQLException(e); 623 } 624 } 625 626 private void copyout(byte[] buf, int addr, int count) throws SQLException 627 { 628 try 629 { 630 rt.copyout(buf, addr, count); 631 } 632 catch (Runtime.FaultException e) 633 { 634 throw new CausedSQLException(e); 635 } 430 636 } 431 637 432 638 /** Maps any exception onto an SQLException. */ 433 private static final class CausedSQLException extends SQLException { 639 private static final class CausedSQLException extends SQLException 640 { 434 641 private final Exception cause; 435 CausedSQLException(Exception e) { 436 if (e == null) throw new RuntimeException("null exception cause"); 642 643 CausedSQLException(Exception e) 644 { 645 if (e == null) 646 throw new RuntimeException("null exception cause"); 437 647 cause = e; 438 648 } 439 public Throwable getCause() { return cause; } 440 public void printStackTrace() { cause.printStackTrace(); } 441 public void printStackTrace(PrintWriter s) { cause.printStackTrace(s); } 442 public Throwable fillInStackTrace() { return cause.fillInStackTrace(); } 443 public StackTraceElement[] getStackTrace() { 444 return cause.getStackTrace(); } 445 public String getMessage() { return cause.getMessage(); } 649 650 public Throwable getCause() 651 { 652 return cause; 653 } 654 655 public void printStackTrace() 656 { 657 cause.printStackTrace(); 658 } 659 660 public void printStackTrace(PrintWriter s) 661 { 662 cause.printStackTrace(s); 663 } 664 665 public Throwable fillInStackTrace() 666 { 667 return cause.fillInStackTrace(); 668 } 669 670 public StackTraceElement[] getStackTrace() 671 { 672 return cause.getStackTrace(); 673 } 674 675 public String getMessage() 676 { 677 return cause.getMessage(); 678 } 446 679 } 447 680 }


