/* Copyright 2006 David Crawshaw, see LICENSE file for licensing [BSD]. */
package org.sqlite;

import java.net.URL;
import java.sql.SQLException;

/** This class provides a thin JNI layer over the SQLite3 C API.
 *
 *  All SQLite access is synchronized against the instance of this class,
 *  so a synchronized (db) { ... } block guarantees no-one else can talk
 *  to the database. */
class DB implements Codes
{
    /** database pointer */
    long pointer = 0;

    static {
        URL url = ClassLoader.getSystemResource(
            System.mapLibraryName("sqlitejdbc"));

        if (url == null || "".equals(url.getFile()))
            System.loadLibrary("sqlitejdbc");  // load from java.library.path
        else
            System.load(url.getFile());        // load from classpath

        init();
    }

    private static native void init();


    // WRAPPER FUNCTIONS ////////////////////////////////////////////

    native synchronized void open(String filename) throws SQLException;
    native synchronized void close() throws SQLException;
    native synchronized void interrupt();
    native synchronized void busy_timeout(int ms);
    native synchronized void exec(String sql) throws SQLException;
    native synchronized long prepare(String sql) throws SQLException;
    native synchronized String errmsg();

    native synchronized int changes(long stmt);
    native synchronized int finalize(long stmt);
    native synchronized int step(long stmt);
    native synchronized int reset(long stmt);
    native synchronized int clear_bindings(long stmt);

    native synchronized int bind_parameter_count(long stmt);
    native synchronized int bind_null  (long stmt, int pos);
    native synchronized int bind_text  (long stmt, int pos, String value);
    native synchronized int bind_blob  (long stmt, int pos, byte[] value);
    native synchronized int bind_double(long stmt, int pos, double value);
    native synchronized int bind_long  (long stmt, int pos, long   value);
    native synchronized int bind_int   (long stmt, int pos, int    value);

    native synchronized int    column_count      (long stmt);
    native synchronized int    column_type       (long stmt, int col);
    native synchronized String column_decltype   (long stmt, int col);
    native synchronized String column_table_name (long stmt, int col);
    native synchronized String column_name       (long stmt, int col);
    native synchronized String column_text       (long stmt, int col);
    native synchronized byte[] column_blob       (long stmt, int col);
    native synchronized double column_double     (long stmt, int col);
    native synchronized long   column_long       (long stmt, int col);
    native synchronized int    column_int        (long stmt, int col);


    // COMPOUND FUNCTIONS (for optimisation) /////////////////////////

    native synchronized int executeUpdate(long stmt) throws SQLException;

    native synchronized String[] column_names(long stmt);

    /** Provides metadata for the columns of a statement. Returns:
     *   res[col][0] = true if column constrained NOT NULL
     *   res[col][1] = true if column is part of the primary key
     *   res[col][2] = true if column is auto-increment
     */
    native synchronized boolean[][] column_metadata(long stmt, String[] names);
    synchronized boolean[][] column_metadata(long stmt) {
        return column_metadata(stmt, column_names(stmt));
    }


    // HELPER FUNCTIONS /////////////////////////////////////////////

    void throwex() throws SQLException { throw ex(); }
    void throwex(String msg) throws SQLException { throw new SQLException(msg);}
    SQLException ex() { return new SQLException("SQLite error: " + errmsg()); }
}

@@ -105,15 +105,15 @@
 ava.
-net.URL
+io.File
 ;%0Aim
@@ -484,60 +484,150 @@
     
-URL url = ClassLoader.getSystemResource(%0A           
+String libpath = System.getProperty(%22org.sqlite.lib.path%22);%0A%0A        if (libpath != null) %7B%0A            try %7B%0A                String libname =
  Sys
@@ -658,19 +658,17 @@
 tejdbc%22)
-);%0A
+;
 %0A       
@@ -672,52 +672,74 @@
     
-if (url == null %7C%7C %22%22.equals(url.getFile()))
+        System.load(new File(libpath, libname).getAbsolutePath());
 %0A   
@@ -751,87 +751,173 @@
     
-System.loadLibrary(%22sqlitejdbc%22);  // load from java.library.path%0A
+%7D catch (UnsatisfiedLinkError e) %7B%0A                throw new RuntimeException(%0A                    %22property org.sqlite.lib.path set but does not reference%22%0A 
        
- else%0A
     
@@ -928,65 +928,128 @@
     
-System.load(url.getFile());        // load from classpath
++ %22 a path containing the SQLiteJDBC native library%22, e);%0A            %7D%0A        %7D else System.loadLibrary(%22sqlitejdbc%22);
 %0A%0A  

switch to loading native library from property 'org.sqlite.lib.path' if set