[PATCH] ROE support for DBI

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] ROE support for DBI

Paolo Bonzini-2
I committed two patches that, respectively, merge the ROE package from
SqueakSource and add support for ROE into the database interface.

To do the latter, what was required actually was support for retrieving
the tables' schema information using a Table class and a #tableAt:
method on the connection.  ROE support came for free then (half a dozen
methods, all in the abstract class).

Paolo

diff --git a/NEWS b/NEWS
index 03b552f..1930c0f 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,10 @@ o   Unbuffered sockets available from class TCP.StreamSocket.
 
 New goodies:
 
+o   DBI supports querying tables for schema information, and is integrated
+    with the "ROE" (Relational Object Expression) package.  ROE support is
+    present for all back-ends (MySQL, PostgreSQL, SQLite).
+
 o   Swazoo web server
 
 -----------------------------------------------------------------------------
diff --git a/TODO b/TODO
index 6e0b85e..18270ee 100644
--- a/TODO
+++ b/TODO
@@ -32,12 +32,14 @@ FileStream that only shows a segment of the file (done).
 
 * improvements to DBI
 ** refactoring and prepared statements support
-** merge ROE?
+** merge ROE (done)
 
 * cookies and redirects for HTTPClient
 
 * Seaside
 
+* Swazoo (done)
+
 * more libraries
 ** gnutls
 ** 3D gnuplot?
diff --git a/packages/dbd-mysql/ChangeLog b/packages/dbd-mysql/ChangeLog
index 70d8c25..802bba5 100644
--- a/packages/dbd-mysql/ChangeLog
+++ b/packages/dbd-mysql/ChangeLog
@@ -1,5 +1,11 @@
 2008-02-14  Paolo Bonzini  <[hidden email]>
 
+ * Connection.st: Add #primTableAt:ifAbsent:.
+ * Table.st: New.
+ * TableColumnInfo.st: New.
+
+2008-02-14  Paolo Bonzini  <[hidden email]>
+
  * Column.st: Add #isNullable.
 
 2008-02-14  Paolo Bonzini  <[hidden email]>
diff --git a/packages/dbd-mysql/Connection.st b/packages/dbd-mysql/Connection.st
index a77bfab..5dbc097 100644
--- a/packages/dbd-mysql/Connection.st
+++ b/packages/dbd-mysql/Connection.st
@@ -757,6 +757,19 @@ Connection subclass: MySQLConnection [
  result at: 2 put: ((array1 at: 2) bitXor: (array2 at: 2)) \\ 1073741823.
  ^result
     ]
+
+    primTableAt: aString ifAbsent: aBlock [
+ | table |
+ [
+    table := (MySQLTable name: aString connection: self)
+ columnsArray;
+ yourself ]
+    on: Error
+    do: [ :ex | ex return ].
+
+ table isNil ifTrue: [ ^aBlock value ].
+ ^table
+    ]
 ]
 
 
diff --git a/packages/dbd-mysql/Makefile.frag b/packages/dbd-mysql/Makefile.frag
index cace236..38976e9 100644
--- a/packages/dbd-mysql/Makefile.frag
+++ b/packages/dbd-mysql/Makefile.frag
@@ -1,5 +1,5 @@
 DBD-MySQL_FILES = \
-packages/dbd-mysql/Column.st packages/dbd-mysql/Connection.st packages/dbd-mysql/Extensions.st packages/dbd-mysql/MySQLTests.st packages/dbd-mysql/ResultSet.st packages/dbd-mysql/Row.st packages/dbd-mysql/Statement.st packages/dbd-mysql/ChangeLog
+packages/dbd-mysql/Column.st packages/dbd-mysql/Connection.st packages/dbd-mysql/Extensions.st packages/dbd-mysql/MySQLTests.st packages/dbd-mysql/ResultSet.st packages/dbd-mysql/Row.st packages/dbd-mysql/Statement.st packages/dbd-mysql/Table.st packages/dbd-mysql/TableColumnInfo.st packages/dbd-mysql/ChangeLog
 $(DBD-MySQL_FILES):
 $(srcdir)/packages/dbd-mysql/stamp-classes: $(DBD-MySQL_FILES)
  touch $(srcdir)/packages/dbd-mysql/stamp-classes
diff --git a/packages/dbd-mysql/Table.st b/packages/dbd-mysql/Table.st
new file mode 100644
index 0000000..2556914
--- /dev/null
+++ b/packages/dbd-mysql/Table.st
@@ -0,0 +1,56 @@
+"=====================================================================
+|
+|   MySQL DBI driver - Table class
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2008 Free Software Foundation, Inc.
+| Written by Paolo Bonzini
+|
+| Copyright 2003, 2007, 2008 Free Software Foundation, Inc.
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+|
+| The GNU Smalltalk class library 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 Lesser
+| General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.  
+|
+ ======================================================================
+"
+
+
+
+Table subclass: MySQLTable [
+    
+    <category: 'DBD-MySQL'>
+    <comment: nil>
+
+    | columnsArray |
+
+    columnsArray [
+ "Answer an array of column name -> ColumnInfo pairs."
+ | query resultSet i |
+ columnsArray isNil ifTrue: [
+    query := 'show columns from `%2`.`%1`' % {
+    self name. self connection database }.
+    resultSet := self connection select: query.
+    i := 0.
+    columnsArray := resultSet rows collect: [ :row |
+ MySQLTableColumnInfo from: row index: (i := i + 1) ] ].
+ ^columnsArray
+    ]
+]
diff --git a/packages/dbd-mysql/TableColumnInfo.st b/packages/dbd-mysql/TableColumnInfo.st
new file mode 100644
index 0000000..131db6b
--- /dev/null
+++ b/packages/dbd-mysql/TableColumnInfo.st
@@ -0,0 +1,87 @@
+"=====================================================================
+|
+|   MySQL DBI driver - TableColumnInfo class
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2008 Free Software Foundation, Inc.
+| Written by Paolo Bonzini
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+|
+| The GNU Smalltalk class library 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 Lesser
+| General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.  
+|
+ ======================================================================
+"
+
+
+
+ColumnInfo subclass: MySQLTableColumnInfo [
+    
+    <category: 'DBD-MySQL'>
+    <comment: nil>
+    | name type size nullable index |
+
+    MySQLTableColumnInfo class >> from: aRow index: anInteger [
+ ^self new initializeFrom: aRow index: anInteger
+    ]
+
+    initializeFrom: aRow index: anInteger [
+ | rawType |
+ name := aRow atIndex: 1.
+ rawType := aRow atIndex: 2.
+ nullable := (aRow atIndex: 3) = 'YES'.
+ index := anInteger.
+
+ type := rawType copyUpTo: $(.
+ (type = 'enum' or: [ type = 'set' or: [ rawType includes: $, ]])
+    ifTrue: [ type := rawType ]
+    ifFalse: [ size := (rawType copyAfter: $( ) asInteger ].
+    ]
+
+    name [
+ "Return the name of the column."
+ <category: 'accessing'>
+ ^name
+    ]
+
+    index [
+ "Return the 1-based index of the column in the result set."
+ <category: 'accessing'>
+ ^index
+    ]
+
+    isNullable [
+ "Return whether the column can be NULL."
+ <category: 'accessing'>
+ ^nullable
+    ]
+
+    type [
+ "Return a string containing the type of the column."
+ <category: 'accessing'>
+ ^type
+    ]
+
+    size [
+ "Return the size of the column."
+ <category: 'accessing'>
+ ^size
+    ]
+]
diff --git a/packages/dbd-mysql/package.xml b/packages/dbd-mysql/package.xml
index 94668da..fe3fade 100644
--- a/packages/dbd-mysql/package.xml
+++ b/packages/dbd-mysql/package.xml
@@ -11,6 +11,8 @@
   <filein>ResultSet.st</filein>
   <filein>Row.st</filein>
   <filein>Statement.st</filein>
+  <filein>Table.st</filein>
+  <filein>TableColumnInfo.st</filein>
 
   <test>
     <sunit>DBI.MySQL.DBIMySQLTestSuite</sunit>
@@ -24,5 +26,7 @@
   <file>ResultSet.st</file>
   <file>Row.st</file>
   <file>Statement.st</file>
+  <file>Table.st</file>
+  <file>TableColumnInfo.st</file>
   <file>ChangeLog</file>
 </package>
diff --git a/packages/dbd-postgresql/ChangeLog b/packages/dbd-postgresql/ChangeLog
index 25d36c1..11e5daf 100644
--- a/packages/dbd-postgresql/ChangeLog
+++ b/packages/dbd-postgresql/ChangeLog
@@ -1,5 +1,11 @@
 2008-02-14  Paolo Bonzini  <[hidden email]>
 
+ * Connection.st: Add #primTableAt:ifAbsent:.
+ * Table.st: New.
+ * TableColumnInfo.st: New.
+
+2008-02-14  Paolo Bonzini  <[hidden email]>
+
  * Connection.st: Use Postgres-specific PGFieldConverter.
  * FieldConverter.st: New.
 
diff --git a/packages/dbd-postgresql/Connection.st b/packages/dbd-postgresql/Connection.st
index 0c964eb..5b2c29d 100644
--- a/packages/dbd-postgresql/Connection.st
+++ b/packages/dbd-postgresql/Connection.st
@@ -142,10 +142,16 @@ Connection subclass: PGConnection [
     ]
 
     database [
- <category: 'PG specific'>
+ <category: 'accessing'>
  ^handle database
     ]
 
+    primTableAt: aString ifAbsent: aBlock [
+ | table |
+ table := PGTable name: aString connection: self.
+ table columnsArray isEmpty ifTrue: [ ^aBlock value ].
+ ^table
+    ]
 ]
 
 
diff --git a/packages/dbd-postgresql/Makefile.frag b/packages/dbd-postgresql/Makefile.frag
index a43f503..9fcfc30 100644
--- a/packages/dbd-postgresql/Makefile.frag
+++ b/packages/dbd-postgresql/Makefile.frag
@@ -1,5 +1,5 @@
 DBD-PostgreSQL_FILES = \
-packages/dbd-postgresql/Connection.st packages/dbd-postgresql/ResultSet.st packages/dbd-postgresql/Row.st packages/dbd-postgresql/ColumnInfo.st
+packages/dbd-postgresql/Connection.st packages/dbd-postgresql/ResultSet.st packages/dbd-postgresql/Row.st packages/dbd-postgresql/ColumnInfo.st packages/dbd-postgresql/Table.st packages/dbd-postgresql/TableColumnInfo.st
 $(DBD-PostgreSQL_FILES):
 $(srcdir)/packages/dbd-postgresql/stamp-classes: $(DBD-PostgreSQL_FILES)
  touch $(srcdir)/packages/dbd-postgresql/stamp-classes
diff --git a/packages/dbd-postgresql/Table.st b/packages/dbd-postgresql/Table.st
new file mode 100644
index 0000000..f892fae
--- /dev/null
+++ b/packages/dbd-postgresql/Table.st
@@ -0,0 +1,58 @@
+"=====================================================================
+|
+|   PosgreSQL DBI driver - Table class
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2008 Free Software Foundation, Inc.
+| Written by Paolo Bonzini
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+|
+| The GNU Smalltalk class library 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 Lesser
+| General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.
+|
+ ======================================================================
+"
+
+
+
+Table subclass: PGTable [
+    
+    <category: 'DBD-PostgreSQL'>
+    <comment: nil>
+
+    | columnsArray |
+
+    columnsArray [
+ "Answer a Dictionary of column name -> ColumnInfo pairs (abstract)."
+ | query resultSet |
+ columnsArray isNil ifTrue: [
+    query := 'select column_name, data_type, character_maximum_length,
+        numeric_precision, numeric_precision_radix, numeric_scale,
+        is_nullable, ordinal_position
+ from information_schema.columns
+ where table_name = %1 and table_catalog = %2
+ order by ordinal_position' % {
+    self name printString. self connection database printString }.
+    resultSet := self connection select: query.
+    columnsArray := resultSet rows
+        collect: [ :row | PGTableColumnInfo from: row ] ].
+ ^columnsArray
+    ]
+]
diff --git a/packages/dbd-postgresql/TableColumnInfo.st b/packages/dbd-postgresql/TableColumnInfo.st
new file mode 100644
index 0000000..e22228c
--- /dev/null
+++ b/packages/dbd-postgresql/TableColumnInfo.st
@@ -0,0 +1,98 @@
+"=====================================================================
+|
+|   PosgreSQL DBI driver - TableColumnInfo class
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2008 Free Software Foundation, Inc.
+| Written by Paolo Bonzini
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+|
+| The GNU Smalltalk class library 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 Lesser
+| General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.
+|
+ ======================================================================
+"
+
+
+
+ColumnInfo subclass: PGTableColumnInfo [
+    
+    <category: 'DBD-PostgreSQL'>
+    <comment: nil>
+    | name type size nullable index |
+
+    PGTableColumnInfo class >> from: aRow [
+ ^self new initializeFrom: aRow
+    ]
+
+    initializeFrom: aRow [
+ | prec radix scale |
+ name := aRow atIndex: 1.
+ type := aRow atIndex: 2.
+ size := aRow atIndex: 3.
+ prec := aRow atIndex: 4.
+ radix := aRow atIndex: 5.
+ scale := aRow atIndex: 6.
+ nullable := (aRow atIndex: 7) = 'YES'.
+ index := aRow atIndex: 8.
+
+ radix = 2 ifTrue: [
+    prec := (prec / 3.32192809) ceiling.
+    scale := (scale / 3.32192809) ceiling ].
+
+ size isNil
+    ifTrue: [
+ scale isNil
+    ifFalse: [
+ size := prec + scale.
+ type := '%1(%2,%3)' % {type. prec. scale } ]
+    ifTrue: [ size := prec ] ]
+    ]
+
+    name [
+ "Return the name of the column."
+ <category: 'accessing'>
+ ^name
+    ]
+
+    index [
+ "Return the 1-based index of the column in the result set."
+ <category: 'accessing'>
+ ^index
+    ]
+
+    isNullable [
+ "Return whether the column can be NULL."
+ <category: 'accessing'>
+ ^nullable
+    ]
+
+    type [
+ "Return a string containing the type of the column."
+ <category: 'accessing'>
+ ^type
+    ]
+
+    size [
+ "Return the size of the column."
+ <category: 'accessing'>
+ ^size
+    ]
+]
diff --git a/packages/dbd-postgresql/package.xml b/packages/dbd-postgresql/package.xml
index 6e88888..d9cd2a2 100644
--- a/packages/dbd-postgresql/package.xml
+++ b/packages/dbd-postgresql/package.xml
@@ -8,9 +8,13 @@
   <filein>ResultSet.st</filein>
   <filein>Row.st</filein>
   <filein>ColumnInfo.st</filein>
+  <filein>Table.st</filein>
+  <filein>TableColumnInfo.st</filein>
 
   <file>Connection.st</file>
   <file>ResultSet.st</file>
   <file>Row.st</file>
   <file>ColumnInfo.st</file>
+  <file>Table.st</file>
+  <file>TableColumnInfo.st</file>
 </package>
diff --git a/packages/dbd-sqlite/ChangeLog b/packages/dbd-sqlite/ChangeLog
index dda96c0..0ddd9c8 100644
--- a/packages/dbd-sqlite/ChangeLog
+++ b/packages/dbd-sqlite/ChangeLog
@@ -1,5 +1,11 @@
 2008-02-14  Paolo Bonzini  <[hidden email]>
 
+ * Connection.st: Add #primTableAt:ifAbsent:.
+ * Table.st: New.
+ * TableColumnInfo.st: New.
+
+2008-02-14  Paolo Bonzini  <[hidden email]>
+
  * ColumnInfo.st: Remove two superfluous methods.
 
 2008-02-14  Paolo Bonzini  <[hidden email]>
diff --git a/packages/dbd-sqlite/Connection.st b/packages/dbd-sqlite/Connection.st
index 9f58ee5..90d9433 100644
--- a/packages/dbd-sqlite/Connection.st
+++ b/packages/dbd-sqlite/Connection.st
@@ -108,4 +108,17 @@ Connection subclass: SQLiteConnection [
                     handle: stmtHandle;
                     queryString: aSQLQuery.
     ]
+
+    primTableAt: aString ifAbsent: aBlock [
+ | table |
+ [
+    table := (SQLiteTable name: aString connection: self)
+ columnsArray;
+ yourself ]
+    on: Error
+    do: [ :ex | ex return ].
+
+ table isNil ifTrue: [ ^aBlock value ].
+ ^table
+    ]
 ]
diff --git a/packages/dbd-sqlite/Makefile.frag b/packages/dbd-sqlite/Makefile.frag
index 89a59e9..21834ae 100644
--- a/packages/dbd-sqlite/Makefile.frag
+++ b/packages/dbd-sqlite/Makefile.frag
@@ -1,5 +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
+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/Table.st packages/dbd-sqlite/TableColumnInfo.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
diff --git a/packages/dbd-sqlite/Table.st b/packages/dbd-sqlite/Table.st
new file mode 100644
index 0000000..75b4556
--- /dev/null
+++ b/packages/dbd-sqlite/Table.st
@@ -0,0 +1,58 @@
+"=====================================================================
+|
+|   SQLite bindings, Table class
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2008 Free Software Foundation, Inc.
+| Written by Paolo Bonzini
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+|
+| The GNU Smalltalk class library 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 Lesser
+| General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.
+|
+ ======================================================================
+"
+
+
+
+Table subclass: SQLiteTable [
+    
+    <category: 'DBD-SQLite'>
+    <comment: nil>
+
+    | columnsArray |
+
+    columnsArray [
+ "Answer an array of column name -> ColumnInfo pairs."
+ | query resultSet string i |
+ columnsArray isNil ifTrue: [
+
+    query := 'select sql from (select * from
+ sqlite_master union all select * from sqlite_temp_master)
+ where tbl_name = %1 limit 1;' % { self name printString }.
+    resultSet := self connection select: query.
+    string := (resultSet next atIndex: 1).
+    string := string copyFrom: (string indexOf: $( ) + 1 to: string size - 1.
+    i := 0.
+    columnsArray := (string subStrings: $,) collect: [ :field |
+ SQLiteTableColumnInfo from: field subStrings index: (i := i + 1) ] ].
+ ^columnsArray
+    ]
+]
diff --git a/packages/dbd-sqlite/TableColumnInfo.st b/packages/dbd-sqlite/TableColumnInfo.st
new file mode 100644
index 0000000..93a2802
--- /dev/null
+++ b/packages/dbd-sqlite/TableColumnInfo.st
@@ -0,0 +1,68 @@
+"=====================================================================
+|
+|   SQLite bindings, TableColumnInfo class
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2008 Free Software Foundation, Inc.
+| Written by Paolo Bonzini
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+|
+| The GNU Smalltalk class library 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 Lesser
+| General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.
+|
+ ======================================================================
+"
+
+
+
+ColumnInfo subclass: SQLiteTableColumnInfo [
+    
+    <category: 'DBD-SQLite'>
+    <comment: nil>
+    | name type index |
+
+    SQLiteTableColumnInfo class >> from: aRow index: anInteger [
+ ^self new initializeFrom: aRow index: anInteger
+    ]
+
+    initializeFrom: aRow index: anInteger [
+ name := aRow at: 1.
+ type := aRow at: 2.
+ index := anInteger.
+    ]
+
+    name [
+ "Return the name of the column."
+ <category: 'accessing'>
+ ^name
+    ]
+
+    index [
+ "Return the 1-based index of the column in the result set."
+ <category: 'accessing'>
+ ^index
+    ]
+
+    type [
+ "Return a string containing the type of the column."
+ <category: 'accessing'>
+ ^type
+    ]
+]
diff --git a/packages/dbd-sqlite/package.xml b/packages/dbd-sqlite/package.xml
index a3404b6..e98b7c3 100644
--- a/packages/dbd-sqlite/package.xml
+++ b/packages/dbd-sqlite/package.xml
@@ -15,6 +15,8 @@
   <filein>Statement.st</filein>
   <filein>Row.st</filein>
   <filein>ColumnInfo.st</filein>
+  <filein>Table.st</filein>
+  <filein>TableColumnInfo.st</filein>
   
   <file>SQLite.st</file>
   <file>Connection.st</file>
@@ -22,6 +24,8 @@
   <file>Statement.st</file>
   <file>Row.st</file>
   <file>ColumnInfo.st</file>
+  <file>Table.st</file>
+  <file>TableColumnInfo.st</file>
   
   <file>SQLiteTests.st</file>
 
diff --git a/packages/dbi/ChangeLog b/packages/dbi/ChangeLog
index 3da8f39..dfba1d8 100644
--- a/packages/dbi/ChangeLog
+++ b/packages/dbi/ChangeLog
@@ -1,5 +1,13 @@
 2008-02-14  Paolo Bonzini  <[hidden email]>
 
+ * Connection.st: Add table accessors.
+ * ResultSet.st: Documentation fix.
+ * Row.st: Add #asArray and #asDictionary.
+ * Table.st: New.
+ * TableColumnInfo.st: New.
+
+2008-02-14  Paolo Bonzini  <[hidden email]>
+
  * ColumnInfo.st: Improve printing.
 
 2008-02-14  Paolo Bonzini  <[hidden email]>
diff --git a/packages/dbi/Connection.st b/packages/dbi/Connection.st
index 58140e6..204d9dd 100644
--- a/packages/dbi/Connection.st
+++ b/packages/dbi/Connection.st
@@ -37,6 +37,8 @@ Object subclass: Connection [
     <category: 'DBI-Framework'>
     <comment: 'I represent a connection to a database.'>
 
+    | tables |
+
     Drivers := LookupTable new.
 
     Connection class >> updateDriverList [
@@ -95,6 +97,36 @@ Object subclass: Connection [
     password: aPassword
     ]
 
+    >> aString [
+ "Returns a Table object corresponding to the given table."
+
+ <category: 'accessing'>
+ ^self tableAt: aString
+    ]
+
+    primTableAt: aString ifAbsent: aBlock [
+ "Returns a Table object corresponding to the given table.  Should be
+ overridden by subclasses."
+
+ <category: 'querying'>
+ self subclassResponsibility
+    ]
+
+    tableAt: aString [
+ "Returns a Table object corresponding to the given table."
+
+ <category: 'accessing'>
+ ^self tableAt: aString ifAbsent: [self error: 'Unknown table: ', aString]
+    ]
+
+    tableAt: aString ifAbsent: aBlock [
+ "Returns a Table object corresponding to the given table."
+
+ <category: 'accessing'>
+ tables isNil ifTrue: [ tables := LookupTable new ].
+ ^tables at: aString ifAbsentPut: [self primTableAt: aString ifAbsent: aBlock]
+    ]
+
     do: aSQLQuery [
  "Executes a SQL statement (usually one that doesn't return a result set).
  Return value is a ResultSet, to which you can send #rowsAffected
diff --git a/packages/dbi/Makefile.frag b/packages/dbi/Makefile.frag
index 7d4bbdb..76d8891 100644
--- a/packages/dbi/Makefile.frag
+++ b/packages/dbi/Makefile.frag
@@ -1,5 +1,5 @@
 DBI_FILES = \
-packages/dbi/ConnectionInfo.st packages/dbi/Connection.st packages/dbi/Statement.st packages/dbi/ResultSet.st packages/dbi/Row.st packages/dbi/ColumnInfo.st packages/dbi/Table.st packages/dbi/FieldConverter.st
+packages/dbi/ConnectionInfo.st packages/dbi/Connection.st packages/dbi/Statement.st packages/dbi/ResultSet.st packages/dbi/Row.st packages/dbi/ColumnInfo.st packages/dbi/Table.st packages/dbi/FieldConverter.st packages/dbi/ChangeLog
 $(DBI_FILES):
 $(srcdir)/packages/dbi/stamp-classes: $(DBI_FILES)
  touch $(srcdir)/packages/dbi/stamp-classes
diff --git a/packages/dbi/ResultSet.st b/packages/dbi/ResultSet.st
index fc3e1c8..ee67c26 100644
--- a/packages/dbi/ResultSet.st
+++ b/packages/dbi/ResultSet.st
@@ -72,7 +72,7 @@ case I only hold the number of rows affected.'>
     ]
 
     columns [
- "Answer a Dictionary of column -> index pairs (abstract)."
+ "Answer a Dictionary of column name -> ColumnInfo pairs (abstract)."
 
  <category: 'accessing'>
  self subclassResponsibility
diff --git a/packages/dbi/Row.st b/packages/dbi/Row.st
index ac2cd2b..d15c711 100644
--- a/packages/dbi/Row.st
+++ b/packages/dbi/Row.st
@@ -57,6 +57,23 @@ Object subclass: Row [
  self subclassResponsibility
     ]
 
+    asArray [
+ "Return the values of the columns."
+
+ <category: 'accessing'>
+ ^1 to: self columns size collect: [:index | self atIndex: index]
+    ]
+
+    asDictionary [
+ "Return the names and values of the columns as a dictionary."
+
+ | d |
+ <category: 'accessing'>
+ d := LookupTable new.
+ self keysAndValuesDo: [ :key :value | d at: key put: value ].
+ ^d
+    ]
+
     atIndex: aColumnIndex [
  "Return the value of the column at the given 1-based index (abstract)."
 
diff --git a/packages/dbi/Table.st b/packages/dbi/Table.st
new file mode 100644
index 0000000..0da7f11
--- /dev/null
+++ b/packages/dbi/Table.st
@@ -0,0 +1,105 @@
+"=====================================================================
+|
+|   Generic database interface - Table class (bridge with ROE)
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright 2008 Free Software Foundation, Inc.
+| Written by Paolo Bonzini
+|
+| This file is part of the GNU Smalltalk class library.
+|
+| The GNU Smalltalk class library is free software; you can redistribute it
+| and/or modify it under the terms of the GNU Lesser General Public License
+| as published by the Free Software Foundation; either version 2.1, or (at
+| your option) any later version.
+|
+| The GNU Smalltalk class library 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 Lesser
+| General Public License for more details.
+|
+| You should have received a copy of the GNU Lesser General Public License
+| along with the GNU Smalltalk class library; see the file COPYING.LIB.
+| If not, write to the Free Software Foundation, 59 Temple Place - Suite
+| 330, Boston, MA 02110-1301, USA.
+|
+ ======================================================================
+"
+
+
+
+ROE.RASQLRelation subclass: Table [
+    
+    <category: 'DBI'>
+    <comment: nil>
+
+    | columns |
+
+    basicExec: aString [
+ <category: 'private'>
+ ^connection do: aString
+    ]
+
+    basicQuery: aString [
+ <category: 'private'>
+ ^(connection select: aString) contents
+    ]
+
+    columnsArray [
+ "Answer a Dictionary of column name -> ColumnInfo pairs (abstract)."
+ self subclassResponsibility
+    ]
+
+    columns [
+        <category: 'accessing'>
+        columns isNil
+            ifTrue:
+                [| n array |
+ array := self columnsArray.
+                columns := LookupTable new: array size.
+                array do: [:col | columns at: col name put: col]].
+        ^columns
+    ]
+
+    columnNames [
+ "Answer an array of column names in order (abstract)."
+
+ <category: 'accessing'>
+ ^self columnsArray collect: [:each | self name]
+    ]
+
+    columnAt: aIndex [
+        "Answer the aIndex'th column name."
+
+        <category: 'accessing'>
+        ^(self columnsArray at: aIndex) name
+    ]
+
+    database [
+ "Returns the database name for this table.  This corresponds
+ to the catalog in SQL standard parlance."
+
+ <category: 'accessing'>
+ ^self connection database
+    ]
+
+    discoverAttributes [
+ <category: 'private'>
+ ^self columnsArray
+    collect: [:each | RASimpleAttribute named: each name relation: self]
+    ]
+
+    size [
+ <category: 'core'>
+ ^(self query: self sqlCount) first atIndex: 1
+    ]
+
+    print: anObject on: aStream [
+        <category: 'printing'>
+        self connection fieldConverter print: anObject on: aStream
+    ]
+]
diff --git a/packages/dbi/package.xml b/packages/dbi/package.xml
index 81d6692..5534436 100644
--- a/packages/dbi/package.xml
+++ b/packages/dbi/package.xml
@@ -1,6 +1,7 @@
 <package>
   <name>DBI</name>
   <namespace>DBI</namespace>
+  <prereq>ROE</prereq>
 
   <filein>ConnectionInfo.st</filein>
   <filein>Connection.st</filein>
@@ -8,6 +9,7 @@
   <filein>ResultSet.st</filein>
   <filein>Row.st</filein>
   <filein>ColumnInfo.st</filein>
+  <filein>Table.st</filein>
   <filein>FieldConverter.st</filein>
 
   <file>ConnectionInfo.st</file>
@@ -16,6 +18,7 @@
   <file>ResultSet.st</file>
   <file>Row.st</file>
   <file>ColumnInfo.st</file>
+  <file>Table.st</file>
   <file>FieldConverter.st</file>
 
   <file>ChangeLog</file>
diff --git a/packages/roe/SQLiteTests.st b/packages/roe/SQLiteTests.st
new file mode 100644
index 0000000..4b24c0a
--- /dev/null
+++ b/packages/roe/SQLiteTests.st
@@ -0,0 +1,73 @@
+"=====================================================================
+|
+|   ROE - SQLite-based testing
+|
+|
+ ======================================================================"
+
+"======================================================================
+|
+| Copyright (C) Avi Bryant
+|
+| Permission is hereby granted, free of charge, to any person
+| obtaining a copy of this software and associated documentation
+| files (the `Software'), to deal in the Software without
+| restriction, including without limitation the rights to use,
+| copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the
+| Software is furnished to do so, subject to the following
+| conditions:
+|
+| The above copyright notice and this permission notice shall be
+| included in all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED `AS IS', WITHOUT WARRANTY OF ANY KIND,
+| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+| OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+| HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+| WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+| FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+| OTHER DEALINGS IN THE SOFTWARE.
+|
+ ======================================================================"
+
+RATestSemantics subclass: RATestSQLiteSemantics [
+    | connection |
+    
+    <comment: nil>
+    <category: 'Roe-Tests'>
+
+    connection [
+ <category: 'configuration'>
+ ^connection
+    ]
+
+    createRelation: aString attributes: anArray [
+ <category: 'configuration'>
+ ^self connection >> aString
+    ]
+
+    setUp [
+ <category: 'private'>
+ connection := DBI.Connection connect: 'dbi:SQLite:dbname=test.dat'
+    user: nil password: nil.
+
+ self connection
+    do: 'begin';
+    do: 'create table profs (facultyID integer, name text)';
+    do: 'create table students (studentNumber integer, name text)';
+    do: 'create table students2 (studentNumber integer, name text)';
+    do: 'create table courses (courseNumber integer, title text, prof integer)';
+    do: 'create table enrollment (student integer, course integer)'.
+    
+ super setUp
+    ]
+
+    tearDown [
+ <category: 'private'>
+ self connection do: 'rollback'.
+ self connection close.
+ (File name: connection database) remove
+    ]
+]
diff --git a/packages/roe/package.xml b/packages/roe/package.xml
index 9be05a5..e7fb738 100644
--- a/packages/roe/package.xml
+++ b/packages/roe/package.xml
@@ -7,12 +7,16 @@
   <filein>Array.st</filein>
   <filein>SQL.st</filein>
   <test>
+    <prereq>DBD-SQLite</prereq>
     <filein>Tests.st</filein>
-    <sunit>ROE.RATestMapping ROE.RATestEvaluatorSemantics ROE.RATestSyntax</sunit>
+    <filein>SQLiteTests.st</filein>
+    <sunit>ROE.RATestMapping ROE.RATestEvaluatorSemantics ROE.RATestSyntax
+ ROE.RATestSQLiteSemantics</sunit>
   </test>
 
   <file>Array.st</file>
   <file>Core.st</file>
+  <file>SQLiteTests.st</file>
   <file>SQL.st</file>
   <file>Tests.st</file>
   <file>Extensions.st</file>

_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk