[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Help-smalltalk] [PATCH] SQLite3 bindings
From: |
Paolo Bonzini |
Subject: |
[Help-smalltalk] [PATCH] SQLite3 bindings |
Date: |
Mon, 03 Dec 2007 08:57:46 +0100 |
User-agent: |
Thunderbird 2.0.0.9 (Macintosh/20071031) |
These are contributed by Daniele Sciascia. I only modified them a
little to support DML queries and to improve error reporting.
Paolo
--- orig/configure.ac
+++ mod/configure.ac
@@ -279,6 +279,12 @@ AC_MSG_RESULT($enable_mysql_tests)
GST_PACKAGE_ENABLE([DBD-PostgreSQL], [dbd-postgresql],
[GST_HAVE_LIB(pq, PQconnectdb)],
[ac_cv_lib_pq_PQconnectdb])
+
+GST_PACKAGE_ENABLE([DBD-SQLite], [dbd-sqlite],
+ [AC_CHECK_HEADER([sqlite3.h])],
+ [ac_cv_header_sqlite3_h],
+ [Makefile], [dbd-sqlite3.la])
+
GST_PACKAGE_ENABLE([DBI], [dbi])
GST_PACKAGE_ENABLE([GDBM], [gdbm],
--- orig/tests/testsuite.at
+++ mod/tests/testsuite.at
@@ -148,4 +148,5 @@ AT_OPTIONAL_PACKAGE_TEST([GDBM])
AT_OPTIONAL_PACKAGE_TEST([Iconv])
AT_PACKAGE_TEST([MySQL], [], [$mysqlvars], [test "$enable_mysql_tests" != no])
AT_PACKAGE_TEST([Sport])
+AT_OPTIONAL_PACKAGE_TEST([DBD-SQLite])
AT_OPTIONAL_PACKAGE_TEST([ZLib])
--- /dev/null
+++ mod/packages/dbd-sqlite/ColumnInfo.st
@@ -0,0 +1,95 @@
+"======================================================================
+|
+| SQLite bindings, ColumnInfo class
+|
+|
+ ======================================================================"
+
+
+"======================================================================
+|
+| Copyright 2007 Free Software Foundation, Inc.
+| Written by Daniele Sciascia
+|
+| This is free software; you can redistribute it and/or modify it
+| under the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2, or (at your option) any later version.
+|
+| This code is distributed in the hope that it will be useful, but WITHOUT
+| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+| FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+| details.
+|
+| You should have received a copy of the GNU General Public License along with
+| Mumble; see the file COPYING. If not, write to the Free Software
+| Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+|
+ ======================================================================
+"
+
+
+ColumnInfo subclass: SQLiteColumnInfo [
+ | resultSet index |
+
+ TypeNames := nil.
+
+ SQLiteColumnInfo class >> in: aResultSet at: anIndex [
+ ^(self new)
+ index: anIndex;
+ resultSet: aResultSet;
+ yourself
+ ]
+
+ SQLiteColumnInfo class >> initTypes [
+ TypeNames := LookupTable new.
+ TypeNames at: 1 put: 'Integer'.
+ TypeNames at: 2 put: 'Float'.
+ TypeNames at: 3 put: 'Text'.
+ TypeNames at: 4 put: 'Blob'.
+ TypeNames at: 5 put: 'Null'.
+ ]
+
+ resultSet: aResultSet [
+ <category: 'private'>
+ resultSet := aResultSet
+ ]
+
+ name [
+ <category: 'accessing'>
+ ^resultSet columnAt: self index
+ ]
+
+ index [
+ <category: 'accessing'>
+ ^index
+ ]
+
+ index: anIndex [
+ <category: 'private'>
+ index := anIndex
+ ]
+
+ type [
+ <category: 'accessing'>
+ ^TypeNames at: (resultSet columnTypeAt: self index)
+ ]
+
+ size [
+ "Return the size of the column (abstract)."
+ <category: 'accessing'>
+ self notYetImplemented
+ ]
+
+ printOn: aStream [
+ <category: 'printing'>
+ aStream
+ nextPutAll: self name;
+ nextPut: $(;
+ nextPutAll: self type;
+ nextPut: $)
+ ]
+]
+
+Eval [
+ SQLiteColumnInfo initTypes
+]
--- /dev/null
+++ mod/packages/dbd-sqlite/Connection.st
@@ -0,0 +1,96 @@
+"======================================================================
+|
+| SQLite bindings, Connection class
+|
+|
+ ======================================================================"
+
+
+"======================================================================
+|
+| Copyright 2007 Free Software Foundation, Inc.
+| Written by Daniele Sciascia
+|
+| This is free software; you can redistribute it and/or modify it
+| under the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2, or (at your option) any later version.
+|
+| This code is distributed in the hope that it will be useful, but WITHOUT
+| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+| FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+| details.
+|
+| You should have received a copy of the GNU General Public License along with
+| Mumble; see the file COPYING. If not, write to the Free Software
+| Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+|
+ ======================================================================
+"
+
+
+Connection subclass: SQLiteConnection [
+ | stmtHandles handle |
+
+ <category: 'DBI-Drivers'>
+ <comment: 'I represent a connection to a SQLite database'>
+
+
+ SQLiteConnection class >> paramConnect: params user: aUserName
password: aPassword [
+ <category: 'connecting'>
+ | dbName aSqlite3Handle |
+
+ dbName := params at: 'dbname'
+ ifAbsent: [self error: 'Missing parameter: dbname'].
+ aSqlite3Handle := SQLite3DBHandle open: dbName.
+ ^(self new)
+ initializeWithHandle: aSqlite3Handle;
+ yourself
+ ]
+
+ initializeWithHandle: aSqlite3Handle [
+ handle := aSqlite3Handle.
+ stmtHandles := WeakIdentitySet new.
+ ]
+
+ close [
+ <category: 'connecting'>
+ stmtHandles do: [ :each | each removeToBeFinalized; finalize ].
+ ^handle close
+ ]
+
+ SQLiteConnection class >> driverName [
+ <category: 'initialization'>
+ ^'SQLite'
+ ]
+
+ handle [
+ <category: 'private'>
+ ^handle
+ ]
+
+ finalize [
+ <category: 'private'>
+ self close
+ ]
+
+ do: aSQLQuery [
+ <category: 'querying'>
+ ^(self prepare: aSQLQuery) execute
+ ]
+
+ select: aSQLQuery [
+ <category: 'querying'>
+ ^(self prepare: aSQLQuery) execute
+ ]
+
+ prepare: aSQLQuery [
+ <category: 'querying'>
+ | stmtHandle |
+ stmtHandle := self handle prepare: aSQLQuery.
+ stmtHandle addToBeFinalized.
+ stmtHandles add: stmtHandle.
+ ^(SQLiteStatement on: self)
+ handle: stmtHandle;
+ queryString: aSQLQuery.
+ ]
+]
--- /dev/null
+++ mod/packages/dbd-sqlite/Makefile.am
@@ -0,0 +1,11 @@
+pkglib_LTLIBRARIES = dbd-sqlite3.la
+
+AM_CPPFLAGS = -I$(top_srcdir)/libgst -I$(top_srcdir)/lib-src
+
+gst_module_ldflags = -rpath $(pkglibdir) -release $(VERSION) -module \
+ -no-undefined -export-symbols-regex gst_initModule
+
+dbd_sqlite3_la_SOURCES = sqlite3.c
+dbd_sqlite3_la_LIBADD = -lsqlite3
+dbd_sqlite3_la_LDFLAGS = $(gst_module_ldflags)
+
--- /dev/null
+++ mod/packages/dbd-sqlite/Makefile.frag
@@ -0,0 +1,5 @@
+DBD-SQLite_FILES = \
+packages/dbd-sqlite/SQLite.st packages/dbd-sqlite/Connection.st
packages/dbd-sqlite/ResultSet.st packages/dbd-sqlite/Statement.st
packages/dbd-sqlite/Row.st packages/dbd-sqlite/ColumnInfo.st
packages/dbd-sqlite/SQLiteTests.st
+$(DBD-SQLite_FILES):
+$(srcdir)/packages/dbd-sqlite/stamp-classes: $(DBD-SQLite_FILES)
+ touch $(srcdir)/packages/dbd-sqlite/stamp-classes
--- /dev/null
+++ mod/packages/dbd-sqlite/ResultSet.st
@@ -0,0 +1,157 @@
+"======================================================================
+|
+| SQLite bindings, ResultSet class
+|
+|
+ ======================================================================"
+
+
+"======================================================================
+|
+| Copyright 2007 Free Software Foundation, Inc.
+| Written by Daniele Sciascia
+|
+| This is free software; you can redistribute it and/or modify it
+| under the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2, or (at your option) any later version.
+|
+| This code is distributed in the hope that it will be useful, but WITHOUT
+| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+| FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+| details.
+|
+| You should have received a copy of the GNU General Public License along with
+| Mumble; see the file COPYING. If not, write to the Free Software
+| Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+|
+ ======================================================================
+"
+
+
+ResultSet subclass: SQLiteResultSet [
+ | handle rows columns index |
+
+ SQLiteResultSet class >> on: aStatement [
+ <category: 'instance creation'>
+ ^self new initializeWithStatement: aStatement
+ ]
+
+ initializeWithStatement: aStatement [
+ <category: 'initialization'>
+ index := 0.
+ self statement: aStatement.
+ self handle: (aStatement handle).
+ self isSelect
+ ifTrue: [self populate]
+ ifFalse: [self exec]
+ ]
+
+ exec [
+ <category: 'initialization'>
+ | resCode |
+ resCode := self handle exec.
+ self handle checkError: resCode = 101.
+ rows := handle changes
+ ]
+
+ populate [
+ <category: 'initialization'>
+ | resCode |
+
+ rows := OrderedCollection new.
+ [ resCode := self handle exec.
+ resCode = 100
+ ] whileTrue: [rows addLast:
+ (SQLiteRow forValues: (self handle returnedRow) in:
self)].
+
+ self handle checkError: resCode = 101.
+ ]
+
+ handle [
+ <category: 'private'>
+ ^handle
+ ]
+
+ handle: aSQLite3StmtHandle [
+ <category: 'private'>
+ handle := aSQLite3StmtHandle
+ ]
+
+ next [
+ <category: 'cursor access'>
+ self atEnd ifTrue: [self error: 'No more rows'].
+ index := index + 1.
+ ^self rows at: index
+ ]
+
+ atEnd [
+ <category: 'cursor access'>
+ ^index >= self rowCount
+ ]
+
+ position [
+ <category: 'stream protocol'>
+ ^index
+ ]
+
+ position: anInteger [
+ <category: 'stream protocol'>
+ (anInteger between: 0 and: self size)
+ ifTrue: [ index := anInteger ]
+ ifFalse: [ SystemExceptions.IndexOutOfRange signalOn: self
withIndex: anInteger ].
+ ^index
+ ]
+
+ columns [
+ <category: 'accessing'>
+ columns isNil
+ ifTrue: [| n |
+ n := self handle colCount.
+ columns := LookupTable new: n.
+ 1 to: n do: [:i | columns at: (self columnNames at: i)
+ put: (SQLiteColumnInfo in: self
at: i)]].
+ ^columns
+ ]
+
+ columnNames [
+ <category: 'accessing'>
+ ^self handle colNames
+ ]
+
+ columnTypes [
+ ^self handle colTypes
+ ]
+
+ columnTypeAt: index [
+ ^self columnTypes at: index
+ ]
+
+ isSelect [
+ <category: 'accessing'>
+ ^self statement isSelect
+ ]
+
+ isDML [
+ <category: 'accessing'>
+ ^self statement isSelect not
+ ]
+
+ rows [
+ <category: 'accessing'>
+ ^rows
+ ]
+
+ rowCount [
+ <category: 'accessing'>
+ self isSelect
+ ifTrue: [^self rows size]
+ ifFalse: [^self error: 'Not a SELECT statement.']
+ ]
+
+ rowsAffected [
+ <category: 'accessing'>
+ self isDML
+ ifTrue: [^self rows]
+ ifFalse: [^self error: 'Not a DML statement.']
+ ]
+]
--- /dev/null
+++ mod/packages/dbd-sqlite/Row.st
@@ -0,0 +1,56 @@
+"======================================================================
+|
+| SQLite bindings, Row class
+|
+|
+ ======================================================================"
+
+
+"======================================================================
+|
+| Copyright 2007 Free Software Foundation, Inc.
+| Written by Daniele Sciascia
+|
+| This is free software; you can redistribute it and/or modify it
+| under the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2, or (at your option) any later version.
+|
+| This code is distributed in the hope that it will be useful, but WITHOUT
+| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+| FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+| details.
+|
+| You should have received a copy of the GNU General Public License along with
+| Mumble; see the file COPYING. If not, write to the Free Software
+| Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+|
+ ======================================================================
+"
+
+
+Row subclass: SQLiteRow [
+ | values |
+
+ SQLiteRow class >> forValues: anArray in: aResultSet [
+ ^super new
+ values: anArray;
+ resultSet: aResultSet;
+ yourself
+ ]
+
+ values: anArray [
+ <category: 'private'>
+ values := anArray
+ ]
+
+ at: aColumnName [
+ <category: 'accessing'>
+ ^self atIndex: (resultSet columns at: aColumnName) index
+ ]
+
+ atIndex: aColumnIndex [
+ <category: 'accessing'>
+ ^values at: aColumnIndex
+ ]
+]
+
--- /dev/null
+++ mod/packages/dbd-sqlite/SQLite.st
@@ -0,0 +1,125 @@
+"======================================================================
+|
+| SQLite bindings, bridge to the C library
+|
+|
+ ======================================================================"
+
+
+"======================================================================
+|
+| Copyright 2007 Free Software Foundation, Inc.
+| Written by Daniele Sciascia
+|
+| This is free software; you can redistribute it and/or modify it
+| under the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2, or (at your option) any later version.
+|
+| This code is distributed in the hope that it will be useful, but WITHOUT
+| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+| FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+| details.
+|
+| You should have received a copy of the GNU General Public License along with
+| Mumble; see the file COPYING. If not, write to the Free Software
+| Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+|
+ ======================================================================
+"
+
+
+Object subclass: SQLite3Handle [
+ | db |
+
+ errorMessage [
+ <cCall: 'gst_sqlite3_error_message' returing: #string args: #(#self)>
+ ]
+
+ checkError: aBoolean [
+ aBoolean ifFalse: [ self error: self errorMessage ]
+ ]
+
+ changes [
+ <category: 'sqlite3 wrapper'>
+ <cCall: 'gst_sqlite3_changes' returning: #int args: #(#self)>
+ ]
+]
+
+SQLite3Handle subclass: SQLite3DBHandle [
+ SQLite3DBHandle class >> open: dbname [
+ | result rc |
+ result := self new.
+ rc := result open: dbname.
+ rc = 0 ifFalse: [ self error: 'error: ', rc printString ].
+ ^result
+ ]
+
+ open: dbname [
+ <cCall: 'gst_sqlite3_open' returning: #int args: #(#self #string)>
+ ]
+
+ close [
+ <cCall: 'gst_sqlite3_close' returning: #int args: #(#self)>
+ ]
+
+ prepare: aSQLQuery [
+ ^SQLite3StmtHandle forQuery: aSQLQuery onHandle: db
+ ]
+]
+
+SQLite3Handle subclass: SQLite3StmtHandle [
+ | stmt colCount colTypes colNames returnedRow |
+
+ SQLite3StmtHandle class >> forQuery: aSQLQuery onHandle: aDbHandle [
+ | result rc |
+ result := self new db: aDbHandle.
+ rc := result prepare: aSQLQuery.
+ rc = 0 ifFalse: [ self error: 'error: ', rc printString ].
+ ^result
+ ]
+
+ db [
+ <category: 'private'>
+ ^db
+ ]
+
+ db: aDbHandle [
+ <category: 'private'>
+ db := aDbHandle
+ ]
+
+ finalize [
+ <category: 'private'>
+ <cCall: 'gst_sqlite3_finalize' returning: #int args: #(#self)>
+ ]
+
+ prepare: aSQLQuery [
+ <category: 'sqlite3 wrapper'>
+ <cCall: 'gst_sqlite3_prepare' returning: #int args: #(#self #string)>
+ ]
+
+ exec [
+ <category: 'sqlite3 wrapper'>
+ <cCall: 'gst_sqlite3_exec' returning: #int args: #(#self)>
+ ]
+
+ colCount [
+ <category: 'accessing'>
+ ^colCount
+ ]
+
+ colTypes [
+ <category: 'accessing'>
+ ^colTypes
+ ]
+
+ colNames [
+ <category: 'accessing'>
+ ^colNames
+ ]
+
+ returnedRow [
+ <category: 'accessing'>
+ ^returnedRow
+ ]
+]
--- /dev/null
+++ mod/packages/dbd-sqlite/SQLiteTests.st
@@ -0,0 +1,159 @@
+"======================================================================
+|
+| SQLite bindings test suite
+|
+|
+ ======================================================================"
+
+
+"======================================================================
+|
+| Copyright 2007 Free Software Foundation, Inc.
+| Written by Daniele Sciascia
+|
+| This is free software; you can redistribute it and/or modify it
+| under the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2, or (at your option) any later version.
+|
+| This code is distributed in the hope that it will be useful, but WITHOUT
+| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+| FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+| details.
+|
+| You should have received a copy of the GNU General Public License along with
+| Mumble; see the file COPYING. If not, write to the Free Software
+| Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+|
+ ======================================================================
+"
+
+
+
+TestCase subclass: SQLiteBaseTest [
+ | connection |
+
+ setUp [
+ | f |
+ f := File name: 'testdb'.
+ f exists ifTrue: [ f remove ].
+ connection := DBI.Connection
+ connect: 'dbi:SQLite:dbname=testdb'
+ user: nil
+ password: nil.
+ connection do: '
+ BEGIN TRANSACTION'.
+ connection do: '
+ CREATE TABLE test(int_field integer, string_field text,
+ double_field double)'.
+ connection do: '
+ INSERT INTO "test" VALUES(1, "one", 1.0)'.
+ connection do: '
+ INSERT INTO "test" VALUES(2, "two", 2.0)'.
+ connection do: '
+ INSERT INTO "test" VALUES(3, "three", 3.0)'.
+ connection do: '
+ COMMIT'.
+ ]
+
+ tearDown [
+ connection close
+ ]
+
+ connection [
+ ^connection
+ ]
+]
+
+SQLiteBaseTest subclass: SQLiteDMLResultSetTestCase [
+ | rs |
+
+ setUp [
+ super setUp.
+ rs := self connection
+ do: 'delete from test where string_field like "t%"'
+ ]
+
+ testRowsAffected [
+ self assert: rs rowsAffected = 2
+ ]
+]
+
+
+SQLiteBaseTest subclass: SQLiteResultSetTestCase [
+ | rs |
+
+ setUp [
+ super setUp.
+ rs := self connection
+ select: 'select * from test'
+ ]
+
+ testNext [
+ self should: [rs position = 0].
+ rs next.
+ self should: [rs position = 1].
+ rs next.
+ self should: [rs position = 2].
+ rs next.
+ self should: [rs atEnd]
+ ]
+
+ testAtEnd [
+ self shouldnt: [rs atEnd].
+ rs next.
+ self shouldnt: [rs atEnd].
+ rs next.
+ self shouldnt: [rs atEnd].
+ rs next.
+ self should: [rs atEnd]
+ ]
+
+ testColumnNames [
+ self should: [rs columnNames = #('int_field' 'string_field'
'double_field')]
+ ]
+
+ testRowCount [
+ self should: [rs rowCount = 3]
+ ]
+]
+
+SQLiteBaseTest subclass: SQLiteRowTestCase [
+ | rs row |
+
+ setUp [
+ super setUp.
+ rs := self connection select: 'select * from test where int_field = 1'.
+ row := rs rows at: 1.
+ ]
+
+ testAt [
+ self should: [(row at: 'int_field') = 1].
+ self should: [(row at: 'string_field') = 'one'].
+ self should: [(row at: 'double_field') = 1.0]
+ ]
+
+ testAtIndex [
+ self should: [(row atIndex: 1) = 1].
+ self should: [(row atIndex: 2) = 'one'].
+ self should: [(row atIndex: 3) = 1.0]
+ ]
+]
+
+TestSuite subclass: SQLiteTestSuite [
+ SQLiteTestSuite class >> suite [
+ ^super new initialize
+ ]
+
+ initialize [
+ self name: 'SQLite-Test'.
+ self addTest: (SQLiteResultSetTestCase selector: #testNext).
+ self addTest: (SQLiteResultSetTestCase selector: #testAtEnd).
+ self addTest: (SQLiteResultSetTestCase selector: #testColumnNames).
+ self addTest: (SQLiteResultSetTestCase selector: #testRowCount).
+
+ self addTest: (SQLiteRowTestCase selector: #testAt).
+ self addTest: (SQLiteRowTestCase selector: #testAtIndex).
+
+ self addTest: (SQLiteDMLResultSetTestCase selector: #testRowsAffected).
+ ]
+]
--- /dev/null
+++ mod/packages/dbd-sqlite/Statement.st
@@ -0,0 +1,89 @@
+"======================================================================
+|
+| SQLite bindings, Statement class
+|
+|
+ ======================================================================"
+
+
+"======================================================================
+|
+| Copyright 2007 Free Software Foundation, Inc.
+| Written by Daniele Sciascia
+|
+| This is free software; you can redistribute it and/or modify it
+| under the terms of the GNU General Public License as published by the Free
+| Software Foundation; either version 2, or (at your option) any later version.
+|
+| This code is distributed in the hope that it will be useful, but WITHOUT
+| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+| FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+| details.
+|
+| You should have received a copy of the GNU General Public License along with
+| Mumble; see the file COPYING. If not, write to the Free Software
+| Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+|
+ ======================================================================
+"
+
+
+
+Statement subclass: SQLiteStatement [
+ | handle queryString isSelect |
+
+ <category: 'DBI-Drivers'>
+ <comment: 'I represent a SQLite prepared statement'>
+
+ SelectQueries := #('EXPLAIN' 'SELECT') asSet.
+
+ handle [
+ <category: 'private'>
+ ^handle
+ ]
+
+ handle: aSqlite3StmtHandle [
+ <category: 'private'>
+ handle := aSqlite3StmtHandle
+ ]
+
+ queryString [
+ <category: 'accessing'>
+ ^queryString
+ ]
+
+ queryString: aSQLQuery [
+ <category: 'accessing'>
+ queryString := aSQLQuery.
+
+ ]
+
+ isSelect [
+ <category: 'accessing'>
+ isSelect isNil
+ ifTrue: [isSelect := SelectQueries includes: self getCommand].
+ ^isSelect
+ ]
+
+ execute [
+ <category: 'querying'>
+ ^SQLiteResultSet on: self
+ ]
+
+ executeWithAll: aParams [
+ <category: 'querying'>
+ self notYetImplemented
+ ]
+
+ getCommand [
+ <category: 'private'>
+ | readStream writeStream aCharacter |
+ writeStream := WriteStream on: String new.
+ readStream := ReadStream on: queryString.
+ readStream skipSeparators.
+ [readStream atEnd
+ or: [aCharacter := readStream next. aCharacter isSeparator]]
+ whileFalse: [writeStream nextPut: aCharacter asUppercase].
+ ^writeStream contents
+ ]
+]
--- /dev/null
+++ mod/packages/dbd-sqlite/package.xml
@@ -0,0 +1,27 @@
+<package>
+ <name>DBD-SQLite</name>
+ <prereq>DBI</prereq>
+ <namespace>DBI.SQLite</namespace>
+ <module>dbd-sqlite3</module>
+
+ <filein>SQLite.st</filein>
+ <filein>Connection.st</filein>
+ <filein>ResultSet.st</filein>
+ <filein>Statement.st</filein>
+ <filein>Row.st</filein>
+ <filein>ColumnInfo.st</filein>
+
+ <file>SQLite.st</file>
+ <file>Connection.st</file>
+ <file>ResultSet.st</file>
+ <file>Statement.st</file>
+ <file>Row.st</file>
+ <file>ColumnInfo.st</file>
+
+ <test>
+ <sunit>DBI.SQLite.SQLiteTestSuite</sunit>
+ <filein>SQLiteTests.st</filein>
+ </test>
+
+ <file>SQLiteTests.st</file>
+</package>
--- /dev/null
+++ mod/packages/dbd-sqlite/sqlite3.c
@@ -0,0 +1,248 @@
+/******************************* -*- C -*- ****************************
+ *
+ * SQLite bindings
+ *
+ *
+ ***********************************************************************/
+
+/***********************************************************************
+ *
+ * Copyright 2007 Free Software Foundation, Inc.
+ * Written by Daniele Sciascia.
+ *
+ * This file is part of GNU Smalltalk.
+ *
+ * GNU Smalltalk is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2, or (at your option) any later
+ * version.
+ *
+ * Linking GNU Smalltalk statically or dynamically with other modules is
+ * making a combined work based on GNU Smalltalk. Thus, the terms and
+ * conditions of the GNU General Public License cover the whole
+ * combination.
+ *
+ * In addition, as a special exception, the Free Software Foundation
+ * give you permission to combine GNU Smalltalk with free software
+ * programs or libraries that are released under the GNU LGPL and with
+ * independent programs running under the GNU Smalltalk virtual machine.
+ *
+ * You may copy and distribute such a system following the terms of the
+ * GNU GPL for GNU Smalltalk and the licenses of the other code
+ * concerned, provided that you include the source code of that other
+ * code when and as the GNU GPL requires distribution of source code.
+ *
+ * Note that people who make modified versions of GNU Smalltalk are not
+ * obligated to grant this special exception for their modified
+ * versions; it is their choice whether to do so. The GNU General
+ * Public License gives permission to release a modified version without
+ * this exception; this exception also makes it possible to release a
+ * modified version which carries forward this exception.
+ *
+ * GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Smalltalk; see the file COPYING. If not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ ***********************************************************************/
+
+
+#include <stdio.h>
+#include "gstpub.h"
+#include "sqlite3.h"
+
+typedef struct st_Sqlite3Handle
+{
+ OBJ_HEADER;
+ OOP db;
+} *SQLite3Handle;
+
+typedef struct st_SQLite3StmtHandle
+{
+ OBJ_HEADER;
+ OOP db;
+ OOP stmt;
+ OOP colCount;
+ OOP colTypes;
+ OOP colNames;
+ OOP returnedRow;
+} *SQLite3StmtHandle;
+
+
+static VMProxy *vmProxy;
+
+
+int
+gst_sqlite3_open (OOP self, const char *db_name)
+{
+ int rc;
+ sqlite3 *db;
+ OOP dbHandle;
+ SQLite3Handle h;
+
+ rc = sqlite3_open (db_name, &db);
+ dbHandle = vmProxy->cObjectToOOP (db);
+ h = (SQLite3Handle) OOP_TO_OBJ (self);
+ h->db = dbHandle;
+
+ return rc;
+}
+
+int
+gst_sqlite3_close (OOP self)
+{
+ sqlite3 *db;
+ SQLite3Handle h;
+
+ h = (SQLite3Handle) OOP_TO_OBJ (self);
+ db = (sqlite3 *) vmProxy->OOPToCObject (h->db);
+ return sqlite3_close (db);
+}
+
+int
+gst_sqlite3_prepare (OOP self, const char *sql)
+{
+ int rc, i, cols;
+ sqlite3 *db;
+ sqlite3_stmt *stmt;
+ OOP tmpOOP;
+ SQLite3StmtHandle h;
+
+ h = (SQLite3StmtHandle) OOP_TO_OBJ (self);
+ db = (sqlite3 *) vmProxy->OOPToCObject (h->db);
+
+ rc = sqlite3_prepare (db, sql, -1, &stmt, 0);
+ tmpOOP = vmProxy->cObjectToOOP (stmt);
+ h->stmt = tmpOOP;
+
+ if (rc != SQLITE_OK)
+ return rc;
+
+ cols = sqlite3_column_count (stmt);
+
+ tmpOOP = vmProxy->intToOOP (cols);
+ h->colCount = tmpOOP;
+
+ tmpOOP = vmProxy->objectAlloc (vmProxy->arrayClass, cols);
+ h->colTypes = tmpOOP;
+
+ tmpOOP = vmProxy->objectAlloc (vmProxy->arrayClass, cols);
+ h->colNames = tmpOOP;
+
+ tmpOOP = vmProxy->objectAlloc (vmProxy->arrayClass, cols);
+ h->returnedRow = tmpOOP;
+
+ for (i = 0; i < cols; i++)
+ {
+ tmpOOP = vmProxy->stringToOOP (sqlite3_column_name (stmt, i));
+ vmProxy->OOPAtPut (h->colNames, i, tmpOOP);
+ }
+
+ return rc;
+}
+
+int
+gst_sqlite3_exec (OOP self)
+{
+ int rc;
+ sqlite3_stmt *stmt;
+ SQLite3StmtHandle h;
+
+ h = (SQLite3StmtHandle) OOP_TO_OBJ (self);
+ stmt = (sqlite3_stmt *) vmProxy->OOPToCObject (h->stmt);
+
+ rc = sqlite3_step (stmt);
+
+ if (rc == SQLITE_ROW)
+ {
+ int i, cols, type;
+ OOP tmpOOP;
+
+ cols = sqlite3_column_count (stmt);
+ for (i = 0; i < cols; i++)
+ {
+ type = sqlite3_column_type (stmt, i);
+ tmpOOP = vmProxy->intToOOP (type);
+ vmProxy->OOPAtPut (h->colTypes, i, tmpOOP);
+
+ switch (type)
+ {
+ case SQLITE_INTEGER:
+ tmpOOP = vmProxy->intToOOP (sqlite3_column_int (stmt, i));
+ break;
+ case SQLITE_FLOAT:
+ tmpOOP = vmProxy->floatToOOP (sqlite3_column_double (stmt, i));
+ break;
+ case SQLITE_TEXT:
+ tmpOOP = vmProxy->stringToOOP (sqlite3_column_text (stmt, i));
+ break;
+ case SQLITE_BLOB:
+ tmpOOP = vmProxy->stringToOOP (sqlite3_column_text (stmt, i));
+ break;
+ case SQLITE_NULL:
+ tmpOOP = vmProxy->nilOOP;
+ break;
+ default:
+ fprintf (stderr, "sqlite3 error: %s\n",
+ "returned type not recognized");
+ }
+
+ vmProxy->OOPAtPut (h->returnedRow, i, tmpOOP);
+ }
+ }
+
+ return rc;
+}
+
+const char *
+gst_sqlite3_error_message (OOP self)
+{
+ sqlite3 *db;
+ SQLite3Handle h;
+
+ h = (SQLite3Handle) OOP_TO_OBJ (self);
+ db = (sqlite3 *) vmProxy->OOPToCObject (h->db);
+
+ return sqlite3_errmsg (db);
+}
+
+int
+gst_sqlite3_finalize (OOP self)
+{
+ sqlite3_stmt *stmt;
+ SQLite3StmtHandle h;
+
+ h = (SQLite3StmtHandle) OOP_TO_OBJ (self);
+ stmt = (sqlite3_stmt *) vmProxy->OOPToCObject (h->stmt);
+
+ return sqlite3_finalize (stmt);
+}
+
+int
+gst_sqlite3_changes (OOP self)
+{
+ sqlite3 *db;
+ SQLite3StmtHandle h;
+
+ h = (SQLite3StmtHandle) OOP_TO_OBJ (self);
+ db = (sqlite3 *) vmProxy->OOPToCObject (h->db);
+
+ return sqlite3_changes (db);
+}
+
+void
+gst_initModule (VMProxy * proxy)
+{
+ vmProxy = proxy;
+ vmProxy->defineCFunc ("gst_sqlite3_open", gst_sqlite3_open);
+ vmProxy->defineCFunc ("gst_sqlite3_close", gst_sqlite3_close);
+ vmProxy->defineCFunc ("gst_sqlite3_prepare", gst_sqlite3_prepare);
+ vmProxy->defineCFunc ("gst_sqlite3_exec", gst_sqlite3_exec);
+ vmProxy->defineCFunc ("gst_sqlite3_changes", gst_sqlite3_changes);
+ vmProxy->defineCFunc ("gst_sqlite3_error_message",
gst_sqlite3_error_message);
+ vmProxy->defineCFunc ("gst_sqlite3_finalize", gst_sqlite3_finalize);
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Help-smalltalk] [PATCH] SQLite3 bindings,
Paolo Bonzini <=