sqlite setBytes () не работает для типа данных BLOB в Windows - PullRequest
0 голосов
/ 31 марта 2011

Я использую sqlite (версия 3.7.5) с драйвером sqlite jdbc, предоставленным на http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC

Я задал почти идентичный вопрос несколько месяцев назад на форумах xerial (http://groups.google.com/group/xerial/browse_thread/thread/ee19bd855e282f9c),), но так и не получил ответа.

Когда я создаю разделяемую библиотеку sqlite.dll / libsqlite.so самостоятельно, мой пример корректно работает в Linux (opensuse 64 bit), но не работает корректно в 32-битной Windows XP professional.

Но если я использую разделяемую библиотеку, предоставленную на веб-сайте sqlite.org (http://sqlite.org/sqlite-dll-win32-x86-3070500.zip) или ту, которая поставляется в комплекте с драйвером jdbc (http://www.xerial.org/maven/repository/artifact/org/xerial/sqlite-jdbc/3.7.2/sqlite-jdbc-3.7.2.jar),, она отлично работает как в Linux, так и в Windows.

Поэтому я предполагаю, что неправильно собираю библиотеку sqlite. Я использую среду cygwin с пакетом Microsoft Platform SDK для создания sqlite. Я использую следующий набор команд для создания библиотеки sqlite в 32-разрядной Windows XP.

mycl -32 -O2 / D "NDEBUG" / MD / D "_WIN32" / D "_WINDOWS" / D "_MBCS" / D "_USRDLL" / D "SQLITE_ENABLE_COLUMN_METADATA" / D "SQLITE_ENABLE_FTS3" / D "SQLITE_THREADSAFE = 1 "-c NativeDB.c -o NativeDB.o

mycl -32 -O2 / D" NDEBUG "/ MD / D" _WIN32 "/ D" _WINDOWS "/ D" _MBCS "/ D"_USRDLL "/ D" SQLITE_ENABLE_COLUMN_METADATA "/ D" SQLITE_ENABLE_FTS3 "/ D" SQLITE_THREADSAFE = 1 "-c sqlite3.c -o sqlite3.o

mylink -32 / DLL / DLL /libpath:../lib/Win32out: sqlite.dll NativeDB.o sqlite3.o gdi32.lib vfw32.lib user32.lib comdlg32.lib comctl32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib wbemuuid.lib netapi32.lib ws2_32

mymt -32 / manifest sqlite.dll.manifest /outputresource:sqlite.dll';#2'

(mycl, mylink и mymt являются оболочками вокруг оригинального cl.exe, ссылки.exe и mt.exe, которые преобразуют аргументы командной строки.Они отлично работают со многими другими проектами, которые я создаю вместе с ними). ​​

Я также создал SSCE для демонстрации проблемы.

package org.sqlite;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class MainDriver {


public static void main(String[] args) {
    new MainDriver();
}


public MainDriver() {

    //Buffers to read and write
    byte[] writeBuffer = new byte[10];
    byte[] readBuffer = null;
    for (int i = 1; i < 10; i++) {
        writeBuffer[i] = (byte)i;
    }

    //Database objects
    Connection conn = null;
    Statement stat = null;
    PreparedStatement prep = null;

    //Load the database driver
    try {
        System.loadLibrary("sqlite");
        Class.forName("org.sqlite.JDBC");
    } catch (Exception e) {
        System.err.println("Could not load sqlite library or instantiate the database driver.");
        System.err.println(e);
        e.printStackTrace();
        return;
    }

    //Open a connection to the database
    try {
        conn = DriverManager.getConnection("jdbc:sqlite:" + "file.db");
    } catch (SQLException e) {
        System.err.println("Could not open a connection to the database with name file.db");
        System.err.println(e);
        e.printStackTrace();
        return;
    }

    //Create a table
    try {
        stat = conn.createStatement();
        stat.execute("CREATE TABLE TEST (model BLOB NOT NULL)");
        stat.close();
    } catch (SQLException e) {
        System.err.println("The table could not be created.");
        System.err.println(e);
        e.printStackTrace();
        return;
    }

    //Write buffer into the database
    try {
        conn.setAutoCommit(false);
        prep = conn.prepareStatement("INSERT INTO TEST (model) VALUES(?)");
        prep.setBytes(1, writeBuffer);
        prep.addBatch();
        prep.executeBatch();
        conn.setAutoCommit(true);
        prep.close();
    } catch (SQLException e) {
        System.err.println("The buffer could not be written to the database.");
        System.err.println(e);
        e.printStackTrace();
        return;
    }

    //Read buffer from the database
    try {
        stat = conn.createStatement();
        ResultSet rs = stat.executeQuery("SELECT * FROM TEST");
        readBuffer = rs.getBytes(1);
        rs.close();
        stat.close();
    } catch (SQLException e) {
        System.err.println("The buffer could not be read");
        System.err.println(e);
        e.printStackTrace();
    }

    //Close the database
    try {
        conn.close();
    } catch (SQLException e) {
        System.err.println("Database could not be closed");
        System.err.println(e);
        e.printStackTrace();
    }

    //Print the buffers
    System.out.print("Write buffer = ");
    for (int i = 0; i < writeBuffer.length; i++) {
        System.out.print(writeBuffer[i]);
    }
    System.out.println();
    System.out.print("Read  buffer = ");
    for (int i = 0; i < readBuffer.length; i++) {
        System.out.print(readBuffer[i]);
    }
    System.out.println();

    //Check the md5sum
    try {
        java.security.MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
        byte[] md5sum = null;
        java.math.BigInteger bigInt = null;

        //Write buffer
        digest.reset();
        digest.update(writeBuffer);
        md5sum = digest.digest();
        bigInt = new java.math.BigInteger(1, md5sum);
        System.out.println("MD5 checksum of write buffer = " + bigInt.toString(16));

        //Read buffer
        digest.reset();
        digest.update(readBuffer);
        md5sum = digest.digest();
        bigInt = new java.math.BigInteger(1, md5sum);
        System.out.println("MD5 checksum of read  buffer = " + bigInt.toString(16));
    } catch (Exception e) {
        System.err.println("MD5 checksum not available");
        return;
    }
}

}

Я также пыталсясоздание sqlite с библиотекой юникод ICU (версия 4.4.2).Я использую следующие команды для сборки sqlite с поддержкой юникода.

cl.exe -32 -O2 / D "NDEBUG" / MD / D "_WIN32" / D "_WINDOWS" / D "_MBCS" / D"_USRDLL" / D "SQLITE_ENABLE_COLUMN_METADATA" / D "SQLITE_ENABLE_FTS3" / D "SQLITE_THREADSAFE = 1" / D "SQLITE_ENABLE_ICU" -I ../ external / icu / win32 / include -I ../ include -c NativeDB.c -oNativeDB.o

cl.exe -32 -O2 / D "NDEBUG" / MD / D "_WIN32" / D "_WINDOWS" / D "_MBCS" / D "_USRDLL" / D "SQLITE_ENABLE_COLUMN_METADATA" / D"SQLITE_ENABLE_FTS3" / D "SQLITE_THREADSAFE = 1" / D "SQLITE_ENABLE_ICU" -I ../ external / icu / win32 / include -I ../ include -c sqlite3.c -o sqlite3.o

ссылка.exe -32 / DLL /libpath:../external/icu/win32/lib /out:sqlite.dll NativeDB.o sqlite3.o icuuc.lib icuin.lib gdi32.lib vfw32.lib user32.lib comdlg32.lib comctl32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib wbemuuid.lib netapi32.lib ws2_32.lib kernel32.lib

mt.exe -32 / манифест sqlite.dll.manifest /outputresource:sqlite.dll'; # 2'

Здание шITH / без Unicode не имеет никакого эффекта.Я все еще не могу решить проблему.Я буду очень признателен за любую помощь или указатели на возможное решение / обходной путь.

1 Ответ

0 голосов
/ 05 апреля 2011

Я наконец решил проблему.Виновником был флаг «NDEBUG», который автоматически добавлялся Visual Studio 6. Следующий набор команд правильно собирает библиотеку sqlite (среда сборки - Microsoft Windows SDK v6.1 - год выпуска 2008).

cl.exe / O2 / GL / D "WIN32" / D "_WINDLL" / D "_UNICODE" / D "ЮНИКОД" / MD / W3 / c / Wp64 / TC / D "SQLITE_ENABLE_COLUMN_METADATA" / D "SQLITE_ENABLE_FTS3" / D "SQLITE_THREADSFE= 1 "/ D" SQLITE_ENABLE_ICU "/ I" ../external/icu/Win32/include "sqlite3.c

cl.exe / O2 / GL / D" WIN32 "/ D" _DLL "/ D"_WINDLL" / D "_UNICODE" / D "ЮНИКОД" / MD / W3 / c / Wp64 / TC / D "SQLITE_ENABLE_COLUMN_METADATA" / D "SQLITE_ENABLE_FTS3" / D "SQLITE_THREADSAFE = 1" / D "SQLITE_ENABD_IC 100.UDB.U*

link.exe / INCREMENTAL: NO / DLL / SUBSYSTEM: CONSOLE / OPT: REF / OPT: ICF / LTCG / MACHINE: X86 /LIBPATH:"../external/icu/Win32/lib "" / out:sqlite.dll "NativeDB.obj sqlite3.obj icuuc.lib icuin.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib

mt.exe / manifest sqlite.dll.manifest /outputresource:sqlite.dll';#2 '

Я публикую команды на случай, если кто-то еще может застрятьта же проблема.

...