fireruby 0.1.0-powerpc-darwin → 0.2.0-powerpc-darwin
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/README +297 -31
- data/examples/example01.rb +60 -0
- data/lib/doc.tar.gz +0 -0
- data/lib/fireruby.bundle +0 -0
- data/lib/mkdoc +1 -1
- data/lib/src.rb +158 -15
- data/test/ConnectionTest.rb +11 -10
- data/test/DDLTest.rb +7 -6
- data/test/DatabaseTest.rb +13 -14
- data/test/GeneratorTest.rb +4 -3
- data/test/ResultSetTest.rb +6 -5
- data/test/RowTest.rb +49 -0
- data/test/SQLTest.rb +43 -26
- data/test/StatementTest.rb +6 -5
- data/test/TransactionTest.rb +7 -6
- data/test/UnitTest.rb +1 -0
- metadata +11 -135
- data/doc/CVS/Entries +0 -10
- data/doc/CVS/Repository +0 -1
- data/doc/CVS/Root +0 -1
- data/doc/classes/CVS/Entries +0 -2
- data/doc/classes/CVS/Entries.Log +0 -1
- data/doc/classes/CVS/Repository +0 -1
- data/doc/classes/CVS/Root +0 -1
- data/doc/classes/FireRuby/CVS/Entries +0 -8
- data/doc/classes/FireRuby/CVS/Entries.Log +0 -7
- data/doc/classes/FireRuby/CVS/Repository +0 -1
- data/doc/classes/FireRuby/CVS/Root +0 -1
- data/doc/classes/FireRuby/Connection.html +0 -364
- data/doc/classes/FireRuby/Connection.src/CVS/Entries +0 -10
- data/doc/classes/FireRuby/Connection.src/CVS/Repository +0 -1
- data/doc/classes/FireRuby/Connection.src/CVS/Root +0 -1
- data/doc/classes/FireRuby/Connection.src/M000046.html +0 -17
- data/doc/classes/FireRuby/Connection.src/M000047.html +0 -17
- data/doc/classes/FireRuby/Connection.src/M000048.html +0 -17
- data/doc/classes/FireRuby/Connection.src/M000049.html +0 -17
- data/doc/classes/FireRuby/Connection.src/M000050.html +0 -17
- data/doc/classes/FireRuby/Connection.src/M000051.html +0 -17
- data/doc/classes/FireRuby/Connection.src/M000052.html +0 -18
- data/doc/classes/FireRuby/Connection.src/M000053.html +0 -18
- data/doc/classes/FireRuby/Connection.src/M000054.html +0 -18
- data/doc/classes/FireRuby/Database.html +0 -292
- data/doc/classes/FireRuby/Database.src/CVS/Entries +0 -7
- data/doc/classes/FireRuby/Database.src/CVS/Repository +0 -1
- data/doc/classes/FireRuby/Database.src/CVS/Root +0 -1
- data/doc/classes/FireRuby/Database.src/M000035.html +0 -17
- data/doc/classes/FireRuby/Database.src/M000036.html +0 -17
- data/doc/classes/FireRuby/Database.src/M000037.html +0 -17
- data/doc/classes/FireRuby/Database.src/M000038.html +0 -18
- data/doc/classes/FireRuby/Database.src/M000039.html +0 -17
- data/doc/classes/FireRuby/Database.src/M000040.html +0 -17
- data/doc/classes/FireRuby/FireRubyError.html +0 -221
- data/doc/classes/FireRuby/FireRubyError.src/CVS/Entries +0 -6
- data/doc/classes/FireRuby/FireRubyError.src/CVS/Repository +0 -1
- data/doc/classes/FireRuby/FireRubyError.src/CVS/Root +0 -1
- data/doc/classes/FireRuby/FireRubyError.src/M000041.html +0 -17
- data/doc/classes/FireRuby/FireRubyError.src/M000042.html +0 -17
- data/doc/classes/FireRuby/FireRubyError.src/M000043.html +0 -17
- data/doc/classes/FireRuby/FireRubyError.src/M000044.html +0 -17
- data/doc/classes/FireRuby/FireRubyError.src/M000045.html +0 -17
- data/doc/classes/FireRuby/Generator.html +0 -343
- data/doc/classes/FireRuby/Generator.src/CVS/Entries +0 -9
- data/doc/classes/FireRuby/Generator.src/CVS/Repository +0 -1
- data/doc/classes/FireRuby/Generator.src/CVS/Root +0 -1
- data/doc/classes/FireRuby/Generator.src/M000001.html +0 -17
- data/doc/classes/FireRuby/Generator.src/M000002.html +0 -17
- data/doc/classes/FireRuby/Generator.src/M000003.html +0 -17
- data/doc/classes/FireRuby/Generator.src/M000004.html +0 -17
- data/doc/classes/FireRuby/Generator.src/M000005.html +0 -17
- data/doc/classes/FireRuby/Generator.src/M000006.html +0 -17
- data/doc/classes/FireRuby/Generator.src/M000007.html +0 -17
- data/doc/classes/FireRuby/Generator.src/M000008.html +0 -17
- data/doc/classes/FireRuby/ResultSet.html +0 -343
- data/doc/classes/FireRuby/ResultSet.src/CVS/Entries +0 -10
- data/doc/classes/FireRuby/ResultSet.src/CVS/Repository +0 -1
- data/doc/classes/FireRuby/ResultSet.src/CVS/Root +0 -1
- data/doc/classes/FireRuby/ResultSet.src/M000026.html +0 -17
- data/doc/classes/FireRuby/ResultSet.src/M000027.html +0 -17
- data/doc/classes/FireRuby/ResultSet.src/M000028.html +0 -17
- data/doc/classes/FireRuby/ResultSet.src/M000029.html +0 -17
- data/doc/classes/FireRuby/ResultSet.src/M000030.html +0 -17
- data/doc/classes/FireRuby/ResultSet.src/M000031.html +0 -17
- data/doc/classes/FireRuby/ResultSet.src/M000032.html +0 -17
- data/doc/classes/FireRuby/ResultSet.src/M000033.html +0 -17
- data/doc/classes/FireRuby/ResultSet.src/M000034.html +0 -17
- data/doc/classes/FireRuby/Statement.html +0 -349
- data/doc/classes/FireRuby/Statement.src/CVS/Entries +0 -10
- data/doc/classes/FireRuby/Statement.src/CVS/Repository +0 -1
- data/doc/classes/FireRuby/Statement.src/CVS/Root +0 -1
- data/doc/classes/FireRuby/Statement.src/M000017.html +0 -17
- data/doc/classes/FireRuby/Statement.src/M000018.html +0 -17
- data/doc/classes/FireRuby/Statement.src/M000019.html +0 -17
- data/doc/classes/FireRuby/Statement.src/M000020.html +0 -17
- data/doc/classes/FireRuby/Statement.src/M000021.html +0 -17
- data/doc/classes/FireRuby/Statement.src/M000022.html +0 -17
- data/doc/classes/FireRuby/Statement.src/M000023.html +0 -18
- data/doc/classes/FireRuby/Statement.src/M000024.html +0 -18
- data/doc/classes/FireRuby/Statement.src/M000025.html +0 -17
- data/doc/classes/FireRuby/Transaction.html +0 -484
- data/doc/classes/FireRuby/Transaction.src/CVS/Entries +0 -9
- data/doc/classes/FireRuby/Transaction.src/CVS/Repository +0 -1
- data/doc/classes/FireRuby/Transaction.src/CVS/Root +0 -1
- data/doc/classes/FireRuby/Transaction.src/M000009.html +0 -17
- data/doc/classes/FireRuby/Transaction.src/M000010.html +0 -17
- data/doc/classes/FireRuby/Transaction.src/M000011.html +0 -17
- data/doc/classes/FireRuby/Transaction.src/M000012.html +0 -17
- data/doc/classes/FireRuby/Transaction.src/M000013.html +0 -17
- data/doc/classes/FireRuby/Transaction.src/M000014.html +0 -17
- data/doc/classes/FireRuby/Transaction.src/M000015.html +0 -18
- data/doc/classes/FireRuby/Transaction.src/M000016.html +0 -17
- data/doc/classes/FireRuby.html +0 -116
- data/doc/created.rid +0 -1
- data/doc/files/CVS/Entries +0 -2
- data/doc/files/CVS/Repository +0 -1
- data/doc/files/CVS/Root +0 -1
- data/doc/files/src_rb.html +0 -119
- data/doc/fr_class_index.html +0 -34
- data/doc/fr_file_index.html +0 -27
- data/doc/fr_method_index.html +0 -80
- data/doc/index.html +0 -24
- data/doc/rdoc-style.css +0 -175
- data/test/example.c +0 -91
- data/test/fb.c +0 -297
- data/test/mfb +0 -1
- data/test/sql_unit_test.fdb +0 -0
- data/test/test.fdb +0 -0
data/doc/README
CHANGED
@@ -1,39 +1,305 @@
|
|
1
|
-
|
1
|
+
== FireRuby Version 0.2.0
|
2
|
+
This is the second release of the FireRuby library. FireRuby is an extension to
|
3
|
+
the Ruby language that provides access to the functionality of the Firebird
|
4
|
+
relational database management system.
|
2
5
|
|
3
|
-
|
4
|
-
provides an interface to the Firebird open source database management system.
|
5
|
-
The library has been developed as an extension to the Ruby language using the
|
6
|
-
Ruby interface API. The library is provided in binary form only to avoid
|
7
|
-
compilation issues.
|
6
|
+
Still no Linux build as I don't have a Linux box to build it on.
|
8
7
|
|
9
|
-
|
10
|
-
it is simply that I do not have access to a Linux box to build it. I hope to
|
11
|
-
rectify this situation in the future but there is no definite timetable for
|
12
|
-
doing this yet.
|
8
|
+
== Enhancements & Alterations
|
13
9
|
|
14
|
-
|
10
|
+
This release sees a switch away from returning arrays containing the row data
|
11
|
+
for queries. Calling the fetch method on a ResultSet object returns an object
|
12
|
+
of the new Row class. This class possesses a lot more information on the row
|
13
|
+
data, including the column name, column aliases, row number and column data.
|
14
|
+
See the API documentation for more information on this class.
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
A change has been made to the Database and Connection classes. Previously the
|
17
|
+
database user name and password was specified when creating a Database object.
|
18
|
+
This didn't make sense so the user name and password have now been switched to
|
19
|
+
be parameters of the connect method. The Connection class has also be updated
|
20
|
+
to reflect this change. Apologies if this breaks existing code but this kind of
|
21
|
+
change is better done sooner rather than later.
|
22
|
+
|
23
|
+
A few additional methods have been added to the existing class set. The
|
24
|
+
ResultSet class now has a method call exhausted? that can be used to detect
|
25
|
+
when there are no more rows available (the fetch method must have been called
|
26
|
+
at least once however). The Statement object now has a parameter_count method
|
27
|
+
that returns a count of the number of parameters require for the execution of
|
28
|
+
the SQL statement.
|
29
|
+
|
30
|
+
Also improved the documentation a little, by adding in the missing documentation
|
31
|
+
for the Blob class, including a piece on the actual usage of the library in
|
32
|
+
code, and adding a source example.
|
33
|
+
|
34
|
+
== Bug Fixes
|
35
|
+
|
36
|
+
A problem with using scalar numeric values as a parameter to an insert
|
37
|
+
Statement was corrected and the whole area of input parameter type conversion
|
38
|
+
tidied up a little.
|
19
39
|
|
20
40
|
== Issues
|
21
41
|
|
22
42
|
Nothing is perfect so this section outlines those issues that are known to
|
23
|
-
exist
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
43
|
+
exist as of this release.
|
44
|
+
|
45
|
+
- The library currently does not support array columns. This may be implemented
|
46
|
+
for a later release depending on demand.
|
47
|
+
|
48
|
+
- There is an issue with the use of anonymous transactions inside of a block
|
49
|
+
for the Database#connect method. An attempt is made to close the connection
|
50
|
+
when the block exits. If, within the block, there is a call to the
|
51
|
+
Connection#execute_immediate method that generates a result set and,
|
52
|
+
subsequently, an exception is raised the anonymous transaction used in the
|
53
|
+
execute_immediate will be unavailable for closure. This will, in turn,
|
54
|
+
make it impossible to close the connection, resulting in an exception. As
|
55
|
+
a work around, don't use anonymous transactions for queries.
|
56
|
+
|
57
|
+
== Installation & Usage
|
58
|
+
|
59
|
+
The library is provided as a gem and built for use with Ruby 1.8+. Testing
|
60
|
+
against an earlier release of Ruby has not been performed. Installation requires
|
61
|
+
the Ruby Gems package to be installed. Assuming that these installation criteria
|
62
|
+
have been met the library can be installed on Windows by executing a command
|
63
|
+
such as the following...
|
64
|
+
|
65
|
+
gem install fireruby-0.2.0-mswin32.gem
|
66
|
+
|
67
|
+
On the Mac OS X platform you may require super user privilege if your Ruby is
|
68
|
+
installed to the default location (i.e. /usr/local/lib). In this case you can
|
69
|
+
use the sudo command to make the installation like this...
|
70
|
+
|
71
|
+
sudo gem install fireruby-0.2.0-powerpc-darwin.gem
|
72
|
+
|
73
|
+
Once the gem installation is complete the FireRuby functionality can be accessed
|
74
|
+
in code with the usual gem style requires...
|
75
|
+
|
76
|
+
require 'rubygems'
|
77
|
+
require_gem 'fireruby'
|
78
|
+
|
79
|
+
== Build Details
|
80
|
+
|
81
|
+
The FireRuby library is an extension of the Ruby language written in C. For Mac
|
82
|
+
OS X the library was built against Firebird installed as a framework, version
|
83
|
+
1.5.1, and with Ruby version 1.8.2. For the Windows platform the library was
|
84
|
+
built against a Ruby installation created using the one-click installer, version
|
85
|
+
1.8.2. The Windows build was created using the freely available Microsoft
|
86
|
+
compilers and SDKs and built against a standard installation of Firebird,
|
87
|
+
version 1.5.2.
|
88
|
+
|
89
|
+
== So How Do I Use It?
|
90
|
+
|
91
|
+
This section will provide some examples of usage for the the FireRuby classes.
|
92
|
+
Throughout the code the following set of assumptions are made.
|
93
|
+
|
94
|
+
- The user name and password that will be employed to attach to the database
|
95
|
+
are 'sysdba' and 'masterkey' respectively (the Firebird defaults).
|
96
|
+
|
97
|
+
- The databases attached to will all be local (i.e. they will all reside on the
|
98
|
+
same machine) as the test code.
|
99
|
+
|
100
|
+
A database, from the Firebird perspective, is made up of one or more files. From
|
101
|
+
a FireRuby perspective a user interaction with a database starts through the
|
102
|
+
Database class. This class provides facilities that allow for creating, dropping
|
103
|
+
and connecting to database instances. For example, to obtain a connection to a
|
104
|
+
database you would use something like the following...
|
105
|
+
|
106
|
+
require 'rubygems'
|
107
|
+
require_gem 'fireruby'
|
108
|
+
|
109
|
+
include FireRuby
|
110
|
+
|
111
|
+
db = Database.new('./test.fdb')
|
112
|
+
c = db.connect('sysdba', 'masterkey')
|
113
|
+
|
114
|
+
This example starts by requiring the necessary files and including the FireRuby
|
115
|
+
module locally - later examples will not detail these lines but they are always
|
116
|
+
required to use the FireRuby code.
|
117
|
+
|
118
|
+
The first line of code after the include creates a new database object. This
|
119
|
+
process does not actually create the database file (see the Database#create
|
120
|
+
method API documentation if that is what you want to do), it simple creates an
|
121
|
+
abstract reference to a database. In creating the Database object we had to
|
122
|
+
provide a database specification string which identifies the database we want to
|
123
|
+
access. In this case we are specifying a database in the current working
|
124
|
+
directory called 'test.fdb'. See the Firebird documentation for details on the
|
125
|
+
structure of more complex database specifications.
|
126
|
+
|
127
|
+
The last line of code in the example given above opens a connection to the
|
128
|
+
database. In doing this we had to provide two parameters, the database user
|
129
|
+
name and password. These are required to gain access to the database.
|
130
|
+
|
131
|
+
A connection represents a conduit to a database and obtaining a connection is a
|
132
|
+
prerequisite to working with the database. The FireRuby library support having
|
133
|
+
multiple connections, to one or more databases, using one or more users, active
|
134
|
+
simultaneously. FireRuby represents a database connection through objects of the
|
135
|
+
Connection class. This class provides functionality to determine the current
|
136
|
+
state a database connection (open or closed) and for closing the connection.
|
137
|
+
Connections take up resources, both locally and on the database server and
|
138
|
+
should be explicitly closed when they are no longer required.
|
139
|
+
|
140
|
+
The connection class also provides a set of conveniences methods to allow for
|
141
|
+
the execution of SQL against a database. These methods, execute_immediate and
|
142
|
+
execute, represently two slightly different approaches to executing SQL against
|
143
|
+
the database. Refer to the API documentation for more information.
|
144
|
+
|
145
|
+
An advantage of using a relational database management system like Firebird is
|
146
|
+
that it provides transactions. A transaction represents a block of work that is
|
147
|
+
either all completed successful or none of it is applied. From the perspective
|
148
|
+
of the database this means that a series of steps that make changes to the
|
149
|
+
tables in the database can be wrapped in a transaction to insure that they
|
150
|
+
either all complete or that none of the changes are applied.
|
151
|
+
|
152
|
+
The FireRuby library represents a database transaction through instances of the
|
153
|
+
Transaction class. There are two ways of obtaining a Transaction using the
|
154
|
+
library, both requiring you to have an open database connection. The first way
|
155
|
+
is to construct a new Transaction object like so...
|
156
|
+
|
157
|
+
tx = Transaction.new(connection)
|
158
|
+
|
159
|
+
The Transaction constructor takes a single parameter which must be either a
|
160
|
+
Connection object or an array of Connection objects. If you pass an array of
|
161
|
+
Connection objects to this constructor then the Transaction created will apply
|
162
|
+
across all of the databases that the connections refer to, allowing you to
|
163
|
+
have transactional control of work that must utilise more than one database. The
|
164
|
+
second way to obtain a transaction is to simply request one from a Connection
|
165
|
+
object, like so.
|
166
|
+
|
167
|
+
tx = connection.start_transaction
|
168
|
+
|
169
|
+
In this case the transaction will only ever apply to one database, the one that
|
170
|
+
the connection relates to. This method also accepts a block, taking a single
|
171
|
+
parameter. The parameter passed to the block will be the transaction created.
|
172
|
+
In this case the lifetime of the transaction is delimited by the block. If the
|
173
|
+
block completes successfully then the work of the transaction will be committed
|
174
|
+
to the database. If the block raises an exception then the transactional work
|
175
|
+
will be rolled back.
|
176
|
+
|
177
|
+
When the block of work associated with a transaction is complete the user must
|
178
|
+
instruct the system to either apply the changes implemented by the work or to
|
179
|
+
discard them. This can be done by calling the commit or rollback methods of the
|
180
|
+
Transaction class respectively. Once a transaction has been committed or rolled
|
181
|
+
back it can no longer be used and should be discarded. Note that attempts to
|
182
|
+
close a connection that has an active transaction against it will fail, so one
|
183
|
+
of the commit or rollback methods should be explictly called in code. The
|
184
|
+
block technique detailed above helps protect against the failure to do this and
|
185
|
+
is a useful technique.
|
186
|
+
|
187
|
+
The Transaction object provides a number of other informational and utility
|
188
|
+
methods. Check the API documentation for this class for more information.
|
189
|
+
|
190
|
+
So we've looked at connections and transactions, but how do we actually do
|
191
|
+
something practical with the database. Well there are a number of possible
|
192
|
+
approaches that we can take to this. Both the Connection and Transaction classes
|
193
|
+
have convenience method for the execution of SQL statements and these are useful
|
194
|
+
for quick SQL. Where you want something that you can repeatedly reuse and,
|
195
|
+
optionally, pass parameters to then you need the Statement class.
|
196
|
+
|
197
|
+
The Statement class represents a SQL statement that has been validated and
|
198
|
+
prepared for execution. Here's an example of creating a SQL statement...
|
199
|
+
|
200
|
+
s = Statement.new(cxn, tx, 'SELECT * FROM MY_TABLE', 3)
|
201
|
+
|
202
|
+
In this example we have created a Statement object that wraps a SQL select from
|
203
|
+
a table called MY_TABLE. The first parameter to the constructor is a Connection
|
204
|
+
object and the second is a Transaction, both mandatory. You may be thinking
|
205
|
+
'why do I need a transaction here, I'm not changing anything?'. This is true
|
206
|
+
(well sort of) but it's a requirement of the underlying database system. This
|
207
|
+
is also the case for the final parameter to the constructor. The value 3 is
|
208
|
+
the SQL dialect to be used with the Statement. This exists for reason arising
|
209
|
+
from the move from closed source Interbase to open source Firebird. The
|
210
|
+
parameter should be given a value of between 1 and 3. If you're not sure what
|
211
|
+
this is and you're only using Firebird it's probably safe to use a value of
|
212
|
+
3 here. Other values are for backward compatibility. Consult the Firebird and
|
213
|
+
Interbase documentation for more details.
|
214
|
+
|
215
|
+
Anyway, now that we have our Statement how do we use it. Well, there are two
|
216
|
+
approaches to using the Statement object. For statements like the one used
|
217
|
+
above, queries that take no parameters, you can use the Statement object to
|
218
|
+
build a ResultSet object, like so...
|
219
|
+
|
220
|
+
r = ResultSet.new(s)
|
221
|
+
|
222
|
+
The ResultSet class will be covered in a little more detail below. The other
|
223
|
+
means by which a Statement can be used is to call one of it's execute methods.
|
224
|
+
The one to be called depends on whether the Statement requires parameters or
|
225
|
+
not. What are parameters you ask? Well, look at the following...
|
226
|
+
|
227
|
+
s = Statement.new(cxn, tx, 'SELECT * FROM MY_TABLE WHERE MYID = ?', 3)
|
228
|
+
|
229
|
+
Note that the SQL select for this Statement contains a '?'. This is a position
|
230
|
+
holder for a value that the statement expects to be provided later. A Statement
|
231
|
+
that wraps such a piece of SQL must be provided with the necessary parameters
|
232
|
+
to execute properly. Where a Statement object represents SQL that requires a
|
233
|
+
parameter then the execute_for method must be called, like this...
|
234
|
+
|
235
|
+
r = s.execute_for([25])
|
236
|
+
|
237
|
+
This code executes the SQL substituting the parameters from the array of data
|
238
|
+
passed to the function call. If a Statement object represents SQL that does not
|
239
|
+
require parameter values a call to the execute method will suffice, such as the
|
240
|
+
following...
|
241
|
+
|
242
|
+
r = s.execute
|
243
|
+
|
244
|
+
The execute methods for the Statement class, as with all of the execute methods
|
245
|
+
for the FireRuby library, have two potential return values. They will either
|
246
|
+
return nil or they will return a ResultSet object. A ResultSet object will only
|
247
|
+
be returned for SQL statements that constitute a query, irrespective of whether
|
248
|
+
that query returns any data. For all other SQL statements the various execute
|
249
|
+
method will return nil.
|
250
|
+
|
251
|
+
A ResultSet object represents a handle by which the data retrieved for a SQL
|
252
|
+
query can be accessed. To fetch a row of data from a ResultSet object you call
|
253
|
+
the fetch method, like the following...
|
254
|
+
|
255
|
+
row = r.fetch
|
256
|
+
|
257
|
+
This fetches a single row of data for a query represented as a Row object (which
|
258
|
+
will be covered shortly). The ResultSet class also provides for iteration across
|
259
|
+
the contents of a result set by providing an each method. The block to the each
|
260
|
+
method will be passed the data for the ResultSet, a row at a time.
|
261
|
+
|
262
|
+
It should be noted that both the Statement and ResultSet objects hold resources
|
263
|
+
while they are active. They both possess close methods and these should be
|
264
|
+
explicitly called to release the associated resources. The exception to this
|
265
|
+
rule is for ResultSets. If you select all of the rows from a ResultSet then the
|
266
|
+
resources for the ResultSet are automatically released. It is still safe to call
|
267
|
+
close on such a ResultSet as this will not cause errors.
|
268
|
+
|
269
|
+
Okay, so you've gotten a row of data in the form of a Row object from your
|
270
|
+
ResultSet, how do we get the data out of it? Well, there are a number of ways
|
271
|
+
of doing this. You can treat the Row object like an array and dereference the
|
272
|
+
columns of data within the row like this...
|
273
|
+
|
274
|
+
value = row[1]
|
275
|
+
|
276
|
+
The index specified to the array dereference operator specifies the column that
|
277
|
+
you want the data for. Column indices start at 0. Alternatively you can use the
|
278
|
+
column name to access the data, like this...
|
279
|
+
|
280
|
+
value = row['MYID']
|
281
|
+
|
282
|
+
This is beneficial as it frees you from the constraint of knowing the ordering
|
283
|
+
of the columns within the row. For more information of the Row class please
|
284
|
+
consult the API documentation.
|
285
|
+
|
286
|
+
Well that covers the bulk of the classes provided by the FireRuby library. The
|
287
|
+
three which haven't been touched upon are the Generator class, the Blob class
|
288
|
+
and the FireRubyException class.
|
289
|
+
|
290
|
+
The Generator class is a wrapper around the Firebird generator facility. A
|
291
|
+
generator, also known as a sequence, provides a means of creating a list of
|
292
|
+
numeric values in a way that is guaranteed to be thread and process safe. Used
|
293
|
+
properly generators can be employed to create unique sequences that make perfect
|
294
|
+
table keys. Consult the API documentation for more details on the Generator
|
295
|
+
class.
|
296
|
+
|
297
|
+
The Blob class is returned as part of the Row object data obtained from a
|
298
|
+
ResultSet. The class wraps the concept of a binary large object stored in the
|
299
|
+
database. Consult the API documentation for further information.
|
300
|
+
|
301
|
+
The FireRubyException class is the error class used by the FireRuby library
|
302
|
+
whenever it hits trouble. If an exception is raised by the FireRuby code then
|
303
|
+
its extremely likely that it will be an instance of this class. The class
|
304
|
+
provides a means of finding out a little more about what exactly has gone
|
305
|
+
wrong. Again, consult the API documentation for more details.
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require_gem 'fireruby'
|
5
|
+
|
6
|
+
include FireRuby
|
7
|
+
|
8
|
+
# SQL constants.
|
9
|
+
CREATE_TABLE_SQL = 'CREATE TABLE TESTTABLE (TESTID INTEGER NOT NULL PRIMARY '\
|
10
|
+
'KEY, TESTTEXT VARCHAR(100), TESTFLOAT NUMERIC(6,2), '\
|
11
|
+
'CREATED TIMESTAMP)'
|
12
|
+
DROP_TABLE_SQL = 'DROP TABLE TESTTABLE'
|
13
|
+
INSERT_SQL = 'INSERT INTO TESTTABLE VALUES(?, ?, ?, ?)'
|
14
|
+
SELECT_SQL = 'SELECT * FROM TESTTABLE'
|
15
|
+
|
16
|
+
begin
|
17
|
+
# Check if the database file exists.
|
18
|
+
db = nil
|
19
|
+
if File.exist?('./example.fdb') == false
|
20
|
+
# Create the database file.
|
21
|
+
db = Database.create('./example.fdb', 'sysdba', 'masterkey', 1024, 'ASCII')
|
22
|
+
else
|
23
|
+
# Create the databse object.
|
24
|
+
db = Database.new('./example.fdb')
|
25
|
+
end
|
26
|
+
|
27
|
+
# Obtain a connection to the database.
|
28
|
+
db.connect('sysdba', 'masterkey') do |cxn|
|
29
|
+
# Create the database table.
|
30
|
+
cxn.execute_immediate(CREATE_TABLE_SQL)
|
31
|
+
|
32
|
+
# Insert 50 rows into the database.
|
33
|
+
decimal = 1.0
|
34
|
+
cxn.start_transaction do |tx|
|
35
|
+
s = Statement.new(cxn, tx, INSERT_SQL, 3)
|
36
|
+
1.upto(20) do |number|
|
37
|
+
s.execute_for([number, "Number is #{number}.", decimal, Time.new])
|
38
|
+
decimal = decimal + 0.24
|
39
|
+
end
|
40
|
+
s.close
|
41
|
+
end
|
42
|
+
|
43
|
+
# Select back the rows inserted and display them
|
44
|
+
rows = cxn.execute_immediate(SELECT_SQL)
|
45
|
+
rows.each do |row|
|
46
|
+
puts "-----"
|
47
|
+
puts "Test Id: #{row['TESTID']}"
|
48
|
+
puts "Test Text: '#{row['TESTTEXT']}'"
|
49
|
+
puts "Test Float: #{row['TESTFLOAT']}"
|
50
|
+
puts "Test Created: #{row['CREATED']}"
|
51
|
+
puts "-----"
|
52
|
+
end
|
53
|
+
rows.close
|
54
|
+
|
55
|
+
# Drop the table.
|
56
|
+
cxn.execute_immediate(DROP_TABLE_SQL)
|
57
|
+
end
|
58
|
+
rescue Excepton => error
|
59
|
+
puts error.message
|
60
|
+
end
|
data/lib/doc.tar.gz
ADDED
Binary file
|
data/lib/fireruby.bundle
CHANGED
Binary file
|
data/lib/mkdoc
CHANGED
@@ -1 +1 @@
|
|
1
|
-
rdoc
|
1
|
+
rdoc -m README src.rb README
|
data/lib/src.rb
CHANGED
@@ -13,7 +13,7 @@ module FireRuby
|
|
13
13
|
#
|
14
14
|
# This class provides the exception type used by the FireRuby library.
|
15
15
|
#
|
16
|
-
class
|
16
|
+
class FireRubyException
|
17
17
|
#
|
18
18
|
# This is the constructor for the FireRubyError class.
|
19
19
|
#
|
@@ -62,20 +62,10 @@ module FireRuby
|
|
62
62
|
# This is the constructor for the Database class.
|
63
63
|
#
|
64
64
|
# ==== Parameters
|
65
|
-
# user:: A string containing the user name that will be used to
|
66
|
-
# connect to the database.
|
67
|
-
# password:: A string containing the user password that will be used to
|
68
|
-
# connect to the database.
|
69
65
|
# file:: A string containing the database file specifier. This can
|
70
66
|
# include details for a remote server if needed.
|
71
67
|
#
|
72
|
-
def initialize(
|
73
|
-
end
|
74
|
-
|
75
|
-
#
|
76
|
-
# This is the accessor for the user database attribute.
|
77
|
-
#
|
78
|
-
def user
|
68
|
+
def initialize(file)
|
79
69
|
end
|
80
70
|
|
81
71
|
|
@@ -93,11 +83,15 @@ module FireRuby
|
|
93
83
|
# block completes. If a block is specified the connection is provided
|
94
84
|
# as a parameter to the block.
|
95
85
|
#
|
86
|
+
# ==== Parameters
|
87
|
+
# user:: The user name to be used in making the connection.
|
88
|
+
# password:: The password to be used in making the connection.
|
89
|
+
#
|
96
90
|
# ==== Exceptions
|
97
91
|
# Exception:: Thrown whenever a problem occurs connecting with the
|
98
92
|
# database.
|
99
93
|
#
|
100
|
-
def connect
|
94
|
+
def connect(user, password)
|
101
95
|
yield(connection)
|
102
96
|
end
|
103
97
|
|
@@ -106,11 +100,15 @@ module FireRuby
|
|
106
100
|
# This method attempts to drop the database referred to by the details
|
107
101
|
# in a Database object.
|
108
102
|
#
|
103
|
+
# ==== Parameters
|
104
|
+
# user:: The user name to be used in dropping the database.
|
105
|
+
# password:: The password to be used in dropping the database.
|
106
|
+
#
|
109
107
|
# ==== Exceptions
|
110
108
|
# FireRubyError:: Thrown whenever a problem occurs dropping the database
|
111
109
|
# instance.
|
112
110
|
#
|
113
|
-
def drop
|
111
|
+
def drop(user, password)
|
114
112
|
end
|
115
113
|
|
116
114
|
|
@@ -148,13 +146,17 @@ module FireRuby
|
|
148
146
|
#
|
149
147
|
# ==== Parameters
|
150
148
|
# database:: A reference to the Database object to be connected to.
|
149
|
+
# user:: A reference to the user name to be used in making the
|
150
|
+
# database connection.
|
151
|
+
# password:: A reference to the user password to be used in making the
|
152
|
+
# connection.
|
151
153
|
#
|
152
154
|
# ==== Exceptions
|
153
155
|
# Exception:: Generated whenever an invalid database is specified to
|
154
156
|
# the method or an issue occurs establishing the database
|
155
157
|
# connection.
|
156
158
|
#
|
157
|
-
def initialize(database)
|
159
|
+
def initialize(database, user, password)
|
158
160
|
end
|
159
161
|
|
160
162
|
|
@@ -195,6 +197,14 @@ module FireRuby
|
|
195
197
|
end
|
196
198
|
|
197
199
|
|
200
|
+
#
|
201
|
+
# This method retrieves the user name that was used in creating a
|
202
|
+
# Connection object.
|
203
|
+
#
|
204
|
+
def user
|
205
|
+
end
|
206
|
+
|
207
|
+
|
198
208
|
#
|
199
209
|
# This method generates a simple descriptive string for a Connection
|
200
210
|
# object.
|
@@ -463,6 +473,15 @@ module FireRuby
|
|
463
473
|
end
|
464
474
|
|
465
475
|
|
476
|
+
#
|
477
|
+
# This method fetches a count of the number of dynamic parameters for
|
478
|
+
# a statement object (i.e. the number of parameters that must be provided
|
479
|
+
# with values before the SQL statement can be executed).
|
480
|
+
#
|
481
|
+
def parameter_count
|
482
|
+
end
|
483
|
+
|
484
|
+
|
466
485
|
#
|
467
486
|
# This method executes the SQL statement within a Statement object. This
|
468
487
|
# method returns a ResultSet object if the statement executed was a SQL
|
@@ -599,6 +618,24 @@ module FireRuby
|
|
599
618
|
end
|
600
619
|
|
601
620
|
|
621
|
+
#
|
622
|
+
# This method is used to determine if all of the rows have been retrieved
|
623
|
+
# from a ResultSet object. This method will always return false until
|
624
|
+
# the fetch method has been called at least once so it cannot be used to
|
625
|
+
# detect a result set that returns no rows.
|
626
|
+
#
|
627
|
+
def exhausted?
|
628
|
+
end
|
629
|
+
|
630
|
+
|
631
|
+
#
|
632
|
+
# This method fetches a count of the total number of rows retrieved
|
633
|
+
# from a result set.
|
634
|
+
#
|
635
|
+
def row_count
|
636
|
+
end
|
637
|
+
|
638
|
+
|
602
639
|
#
|
603
640
|
# This method provides an iterator for the (remaining) rows contained in
|
604
641
|
# a ResultSet object.
|
@@ -628,6 +665,112 @@ module FireRuby
|
|
628
665
|
end
|
629
666
|
|
630
667
|
|
668
|
+
#
|
669
|
+
# This class models a row of data fetched as part of a SQL query.
|
670
|
+
#
|
671
|
+
class Row
|
672
|
+
#
|
673
|
+
# This is the constructor for the Row class. This method shouldn't really
|
674
|
+
# be used as Row objects are automatically created by ResultSets.
|
675
|
+
#
|
676
|
+
# ==== Parameters
|
677
|
+
# results:: The ResultSet object that the row relates to.
|
678
|
+
# data:: An array containing the row data values.
|
679
|
+
# number:: The row number for the new row.
|
680
|
+
#
|
681
|
+
def initialize(results, data, number)
|
682
|
+
end
|
683
|
+
|
684
|
+
#
|
685
|
+
# This is the accessor for the row number attribute. This will generally
|
686
|
+
# reflect the order the row was fetched from the result set in, with 1
|
687
|
+
# being the first row retrieved.
|
688
|
+
#
|
689
|
+
def number
|
690
|
+
end
|
691
|
+
|
692
|
+
|
693
|
+
#
|
694
|
+
# This method fetches a count of the number of columns of data that are
|
695
|
+
# available from a row.
|
696
|
+
#
|
697
|
+
def column_count
|
698
|
+
end
|
699
|
+
|
700
|
+
|
701
|
+
#
|
702
|
+
# This method fetches the name of a column within a row of data.
|
703
|
+
#
|
704
|
+
# ==== Parameters
|
705
|
+
# index:: The index of the column to fetch the name for. The first
|
706
|
+
# column in the row is at offset zero.
|
707
|
+
#
|
708
|
+
def column_name(index)
|
709
|
+
end
|
710
|
+
|
711
|
+
|
712
|
+
#
|
713
|
+
# This method fetches the alias of a column within a row of data.
|
714
|
+
#
|
715
|
+
# ==== Parameters
|
716
|
+
# index:: The index of the column to fetch the alias for. The first
|
717
|
+
# column in the row is at offset zero.
|
718
|
+
#
|
719
|
+
def column_alias(index)
|
720
|
+
end
|
721
|
+
|
722
|
+
|
723
|
+
#
|
724
|
+
# This method fetches the value associated with a column within a Row
|
725
|
+
# object.
|
726
|
+
#
|
727
|
+
# ==== Parameters
|
728
|
+
# index:: Either the offset of the column to retrieve the value of or
|
729
|
+
# the name of the column to retrieve the value of (column name
|
730
|
+
# comparisons are case sensitive).
|
731
|
+
#
|
732
|
+
def [](index)
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
#
|
737
|
+
# This class represents Blob data fetched from the database. The class defers
|
738
|
+
# the actual loading of the blob until requested. The class is somewhat basic
|
739
|
+
# and maybe expanded upon in later releases.
|
740
|
+
#
|
741
|
+
class Blob
|
742
|
+
#
|
743
|
+
# This is the constructor for the Blob class. This shouldn't really be
|
744
|
+
# used outside of the FireRuby library.
|
745
|
+
#
|
746
|
+
def initialize
|
747
|
+
end
|
748
|
+
|
749
|
+
|
750
|
+
#
|
751
|
+
# This method loads the entire data set for a blob as a string.
|
752
|
+
#
|
753
|
+
def to_s
|
754
|
+
end
|
755
|
+
|
756
|
+
|
757
|
+
#
|
758
|
+
# This method closes a blob, freeing any resources associated with it.
|
759
|
+
#
|
760
|
+
def close
|
761
|
+
end
|
762
|
+
|
763
|
+
|
764
|
+
#
|
765
|
+
# This method loads the segments of a blob one after another. The blob
|
766
|
+
# segments are passed as strings to the block passed to the method.
|
767
|
+
#
|
768
|
+
def each
|
769
|
+
yield segment
|
770
|
+
end
|
771
|
+
end
|
772
|
+
|
773
|
+
|
631
774
|
#
|
632
775
|
# This class represents a Firebird generator entity.
|
633
776
|
#
|