rubyfb 0.5.9 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,39 @@
1
+ v0.6.0 ==
2
+ API changes:
3
+ !!WARNING!!
4
+ This version breaks backward compatibility
5
+ The major change is that the statement object is no longer tied to a particular
6
+ transaction, allowing us to have a prepared statement object for use in diffent transactions.
7
+ The transaction is supplied as parameter to the exec*() methods. The removal of the execute()
8
+ and execute_for() metods is an intetional API breakage, the exec() method is a direct
9
+ drop in replacement for both methods, but the transaction context will change, and
10
+ may yeld to unexpected results.
11
+ For the brave - alias(:execute_for, :exec); alias(:execute, :exec); will bring back execute*() methods
12
+ !!WARNING!!
13
+ The Statement constructor signature is chnaged, the recomended way for
14
+ creating new Statement objects is through connection.create_statement() method.
15
+ The Statement execute() and execute_for() methods are gone replaced by the new exec() method.
16
+ New Statement.exec_and_close() method.
17
+ The ResultSet constructor signature is chnaged
18
+ The direct usage of the ResultSet constructor is discouraged
19
+ Blob.each yields binary strings (no character set conversion is performed,
20
+ there is no gurantee that the segments are character aligned)
21
+ Code cleanups:
22
+ Major rewrite of the Statement code
23
+ Major rewrite of the ResultSet code
24
+ Major rewrite of the Generator code
25
+ Bug fixes:
26
+ Fix buffer overflow in Generator code
27
+ Fix BLOB parameters handling
28
+ A lot of adapter related fixes - rubyfb passes the activerecord 3.1 test suite with 33 failures and 23 errors.
29
+ New features:
30
+ Prepared statements support
31
+ Rails 3.1 + cached statements support
32
+
33
+ v0.5.9 ==
34
+ Fix multibyte string handling for BLOB parameters
35
+ Pipe up BLOB encoding when converting to string, or iterating over segments
36
+
1
37
  v0.5.8 ==
2
38
  Merge duplicated code in transaction.execute() and connection.execute()
3
39
  Make #fetch() *always* return nil if #exhausted? - pilcrow/look-before-you-leap
data/Manifest CHANGED
@@ -82,6 +82,7 @@ test/SQLTest.rb
82
82
  test/SQLTypeTest.rb
83
83
  test/ServiceManagerTest.rb
84
84
  test/StatementTest.rb
85
+ test/StoredProcedureTest.rb
85
86
  test/TestSetup.rb
86
87
  test/TransactionTest.rb
87
88
  test/TypeTest.rb
data/README CHANGED
@@ -1,46 +1,15 @@
1
- v0.5.1 =
2
- Initial rubyfb release
3
- To use rubyfb adapter in RoR set your database adpter to "rubyfb"
1
+ === Objective
4
2
 
5
- = FireRuby Version 0.4.1
6
- FireRuby is an extension for the Ruby programming language that provides access
7
- to the Firebird open source RDBMS. The FireRuby library is release under the
8
- Mozilla Public Licence version 1.1 and is free for commercial use.
3
+ The primary goal of the Rubyfb project is to provide Firebird connectivity
4
+ for the Ruby on Rails environment (active record adapter for Firebird database).
9
5
 
10
- ---
11
-
12
- == Enhancements & Alterations
13
-
14
- This release has been brought about as a direct result of efforts to get the
15
- library working on a 64 bit platform. This process exposed some code of
16
- questionable quality. All of the issues raised in getting a 64 bit build have
17
- been addressed and it's only fair that the improvements obtained be passed on
18
- to all platforms. Functionally nothing has changed since the last release and
19
- the new version should replace the old with no problems.
20
-
21
- === Bug Fixes
22
-
23
- A number of bug fixes were implemented as part of the effort to get the library
24
- working on a 64 bit platform. None of these had been raised as bugs against the
25
- library so I have nothing specific to tick off.
26
-
27
- === Backward Compatibility
6
+ The project consists of two parts - the Rubyfb library it self and the adapter code.
7
+ While the primary goal is the Firebird support in RoR, the Rubyfb library
8
+ is kept separated, allowing standalone use and has no RoR dependencies.
28
9
 
29
- Version 0.4.0 of the library made fundamental changes to functionality that was
30
- available in earlier versions of the library. To help accommodate this change
31
- elements were added to support backward compatibility. The relevant details are
32
- listed here...
10
+ === Origin
33
11
 
34
- - Row objects were switched from keying on column names to keying on column
35
- aliases. To revert to the older functionality assign a value of true to the
36
- $FireRubySettings[:ALIAS_KEYS] global setting.
37
-
38
- - DATE columns were switched from being returned as Time objects to be returned
39
- as Date objects. To revert to the older functionality assign a value of true
40
- to the $FireRubySettings[:DATE_AS_DATE] global setting.
41
-
42
- One other point to note is that, as of version 0.4.0, Enumerable is included in
43
- the Row and ResultSet classes.
12
+ Rubyfb library is a fork of the apparently abandoned FireRuby project.
44
13
 
45
14
  === Issues
46
15
 
@@ -48,7 +17,7 @@ Nothing is perfect so this section outlines those issues that are known to
48
17
  exist as of this release.
49
18
 
50
19
  - The service manager functionality does not appear to work on the Mac OS X
51
- platform. I don't believe that this is a problem in the FireRuby code as I
20
+ platform. I don't believe that this is a problem in the Rubyfb code as I
52
21
  have tested the Firebird gbak utility with the -service option and it gives
53
22
  the same result. If anyone knows this to be untrue or of a work around let me
54
23
  know.
@@ -74,7 +43,7 @@ exist as of this release.
74
43
 
75
44
  == Credit Where Credit Is Due
76
45
 
77
- Over its lifetime the FireRuby library has benefitted from input provided by a
46
+ Over its lifetime the FireRuby library has benefited from input provided by a
78
47
  number of individuals. This section acknowledges these inputs...
79
48
 
80
49
  <b>Ken Kunz</b>: Ken has been a strong supporter of the library from early on and
@@ -93,87 +62,32 @@ library.
93
62
 
94
63
  ---
95
64
 
96
- == Installation & Usage
65
+ == Installation
97
66
 
98
- The library is provided as a gem and built for use with Ruby 1.8+. Testing
67
+ The library is provided as a gem for use with Ruby 1.8+. Testing
99
68
  against an earlier release of Ruby has not been performed. Installation requires
100
69
  the Ruby Gems package to be installed. Assuming that these installation criteria
101
- have been met the library can be installed on Windows by executing a command
70
+ have been met the library can be installed by executing a command
102
71
  such as the following...
103
72
 
104
- gem install fireruby-0.4.1-mswin32.gem
73
+ gem install rubyfb
105
74
 
106
- On the Mac OS X platform you may require super user privilege if your Ruby is
75
+ On Linux/Mac OS X platforms you may require super user privilege if your Ruby is
107
76
  installed to the default location (i.e. /usr/local/lib). In this case you can
108
77
  use the sudo command to make the installation like this...
109
78
 
110
- sudo gem install fireruby-0.4.1-powerpc-darwin.gem
79
+ sudo gem install rubyfb
111
80
 
112
- Once the gem installation is complete the FireRuby functionality can be accessed
113
- in code with the usual gem style requires...
114
-
115
- require 'rubygems'
116
- require 'fireruby'
117
-
118
- === Build Details
81
+ === Ruby on Rails usage
119
82
 
120
- The FireRuby library is a Ruby extension written in C. The avoid build issues
121
- binary versions are provided for a number of platforms, including...
83
+ In your database.yml set
84
+ adapter: rubyfb
122
85
 
123
- - Windows: Built against a version of Ruby installed using the one-click
124
- installer and using the freely available Microsoft development tools. This
125
- version was compiled against version 1.5.2 of Firebird.
126
-
127
- - Linux: Built on Ubuntu Linux (Breezy Badger) using a version of Ruby 1.8.2
128
- installed via the Synaptic package manager. This package manager was also
129
- used to make an installation of Firebird.
86
+ See RubyfbAdapter documentation for supported options.
130
87
 
131
- - Mac OS X: Build on version 10.4.3 of OS X against the 1.8.2 version of Ruby
132
- that comes with the operating system. A framework installation of Firebird
133
- version 1.5.1 was used to make the build.
134
-
135
- Its possible to try and build the library on other platforms so I'll provide a
136
- few details as to how to go about doing this. The first step is to download the
137
- CVS tar ball from the Ruby Forge site and expand it into a local directory. This
138
- will create a directory called fireruby. Change into this directory and then
139
- into the fireruby/src subdirectory.
140
-
141
- This directory contains a file called extconf.rb that is used to create the
142
- make file used to build the library. The make file is created by executing this
143
- file but before you do there are a number of parameters that you should be
144
- aware of. The main one of these is --with-firebird-dir. This parameter is used
145
- to indicate the whereabouts of the Firebird headers and libraries. The following
146
- is an example of how this might be used...
147
-
148
- ruby extconf.rb --with-firebird-dir=/usr/local/firebird
149
-
150
- You may need to customise the path for your own Firebird installation. The path
151
- specified should be a directory that contains subdirectories called 'lib' and
152
- 'include'. The lib subdirectory should contain the fbclient shared library and
153
- include should contain the ibase.h header file.
154
-
155
- A note for Windows users. The library requires the free Microsoft C++ compiler,
156
- the Windows SDK, the .NET SDK and nmake to build. If you have all of these
157
- and Firebird installed to default locations then you can create a make file
158
- using the mkmf.bat batch file in the src directory.
159
-
160
- Once you have the make file you can attempt a library build using either make
161
- (on Unix/Linux) or nmake (on Windows). If it builds successfully you can move
162
- on to creating a gem file for installation. To do this, change into the ../gem
163
- directory. In this directory you can do the following (on Windows)...
164
-
165
- make_gem
166
-
167
- ...or the following (on Unix/Linux)...
168
-
169
- ruby make_gem.rb
170
-
171
- This will create the gem file in the main fireruby directory. Install this and
172
- execute the unit tests to check whether you're version is working.
173
-
174
- === So How Do I Use It?
88
+ === Stand alone usage
175
89
 
176
- This section will provide some examples of usage for the the FireRuby classes.
90
+ This section will provide some examples of usage for the the Rubyfb classes.
177
91
  Throughout the code the following set of assumptions are made.
178
92
 
179
93
  - The user name and password that will be employed to attach to the database
@@ -183,22 +97,22 @@ Throughout the code the following set of assumptions are made.
183
97
  same machine) as the test code.
184
98
 
185
99
  A database, from the Firebird perspective, is made up of one or more files. From
186
- a FireRuby perspective a user interaction with a database starts through the
100
+ a Rubyfb perspective a user interaction with a database starts through the
187
101
  Database class. This class provides facilities that allow for creating, dropping
188
102
  and connecting to database instances. For example, to obtain a connection to a
189
103
  database you would use something like the following...
190
104
 
191
105
  require 'rubygems'
192
- require 'fireruby'
106
+ require 'rubyfb'
193
107
 
194
- include FireRuby
108
+ include Rubyfb
195
109
 
196
110
  db = Database.new('./test.fdb')
197
111
  c = db.connect('sysdba', 'masterkey')
198
112
 
199
- This example starts by requiring the necessary files and including the FireRuby
113
+ This example starts by requiring the necessary files and including the Rubyfb
200
114
  module locally - later examples will not detail these lines but they are always
201
- required to use the FireRuby code.
115
+ required to use the Rubyfb code.
202
116
 
203
117
  The first line of code after the include creates a new database object. This
204
118
  process does not actually create the database file (see the Database#create
@@ -214,9 +128,9 @@ database. In doing this we had to provide two parameters, the database user
214
128
  name and password. These are required to gain access to the database.
215
129
 
216
130
  A connection represents a conduit to a database and obtaining a connection is a
217
- prerequisite to working with the database. The FireRuby library support having
131
+ prerequisite to working with the database. The Rubyfb library support having
218
132
  multiple connections, to one or more databases, using one or more users, active
219
- simultaneously. FireRuby represents a database connection through objects of the
133
+ simultaneously. Rubyfb represents a database connection through objects of the
220
134
  Connection class. This class provides functionality to determine the current
221
135
  state a database connection (open or closed) and for closing the connection.
222
136
  Connections take up resources, both locally and on the database server and
@@ -224,7 +138,7 @@ should be explicitly closed when they are no longer required.
224
138
 
225
139
  The connection class also provides a set of conveniences methods to allow for
226
140
  the execution of SQL against a database. These methods, execute_immediate and
227
- execute, represently two slightly different approaches to executing SQL against
141
+ execute, representing two slightly different approaches to executing SQL against
228
142
  the database. Refer to the API documentation for more information.
229
143
 
230
144
  An advantage of using a relational database management system like Firebird is
@@ -234,7 +148,7 @@ of the database this means that a series of steps that make changes to the
234
148
  tables in the database can be wrapped in a transaction to insure that they
235
149
  either all complete or that none of the changes are applied.
236
150
 
237
- The FireRuby library represents a database transaction through instances of the
151
+ The Rubyfb library represents a database transaction through instances of the
238
152
  Transaction class. There are two ways of obtaining a Transaction using the
239
153
  library, both requiring you to have an open database connection. The first way
240
154
  is to construct a new Transaction object like so...
@@ -245,7 +159,7 @@ The Transaction constructor takes a single parameter which must be either a
245
159
  Connection object or an array of Connection objects. If you pass an array of
246
160
  Connection objects to this constructor then the Transaction created will apply
247
161
  across all of the databases that the connections refer to, allowing you to
248
- have transactional control of work that must utilise more than one database. The
162
+ have transactional control of work that must utilize more than one database. The
249
163
  second way to obtain a transaction is to simply request one from a Connection
250
164
  object, like so.
251
165
 
@@ -265,7 +179,7 @@ discard them. This can be done by calling the commit or rollback methods of the
265
179
  Transaction class respectively. Once a transaction has been committed or rolled
266
180
  back it can no longer be used and should be discarded. Note that attempts to
267
181
  close a connection that has an active transaction against it will fail, so one
268
- of the commit or rollback methods should be explictly called in code. The
182
+ of the commit or rollback methods should be explicitly called in code. The
269
183
  block technique detailed above helps protect against the failure to do this and
270
184
  is a useful technique.
271
185
 
@@ -282,59 +196,46 @@ optionally, pass parameters to then you need the Statement class.
282
196
  The Statement class represents a SQL statement that has been validated and
283
197
  prepared for execution. Here's an example of creating a SQL statement...
284
198
 
285
- s = Statement.new(cxn, tx, 'SELECT * FROM MY_TABLE', 3)
199
+ s = connection.create_statement('SELECT * FROM MY_TABLE')
286
200
 
287
201
  In this example we have created a Statement object that wraps a SQL select from
288
- a table called MY_TABLE. The first parameter to the constructor is a Connection
289
- object and the second is a Transaction, both mandatory. You may be thinking
290
- 'why do I need a transaction here, I'm not changing anything?'. This is true
291
- (well sort of) but it's a requirement of the underlying database system. This
292
- is also the case for the final parameter to the constructor. The value 3 is
293
- the SQL dialect to be used with the Statement. This exists for reason arising
294
- from the move from closed source Interbase to open source Firebird. The
295
- parameter should be given a value of between 1 and 3. If you're not sure what
296
- this is and you're only using Firebird it's probably safe to use a value of
297
- 3 here. Other values are for backward compatibility. Consult the Firebird and
298
- Interbase documentation for more details.
299
-
300
- Anyway, now that we have our Statement how do we use it? Well, the answer is
301
- that we call once of the Statement objects execute methods. The one to be called
302
- depends on whether the Statement requires parameters or not. What are parameters
303
- you ask? Well, look at the following...
304
-
305
- s = Statement.new(cxn, tx, 'SELECT * FROM MY_TABLE WHERE MYID = ?', 3)
306
-
307
- Note that the SQL select for this Statement contains a '?'. This is a position
308
- holder for a value that the statement expects to be provided later. A Statement
309
- that wraps such a piece of SQL must be provided with the necessary parameters
310
- to execute properly. Where a Statement object represents SQL that requires a
311
- parameter then the execute_for method must be called, like this...
202
+ a table called MY_TABLE.
312
203
 
313
- s.execute_for([25])
314
-
315
- This code executes the SQL substituting the parameters from the array of data
316
- passed to the function call. If a Statement object represents SQL that does not
317
- require parameter values a call to the execute method will suffice, such as the
318
- following...
204
+ Now that we have our Statement how do we use it? Well, the answer is
205
+ that we call one of the Statement objects exec* methods. The one to be called
206
+ depends on whether we want Rubyfb library to take care of the Statement
207
+ object clean up (i.e. - auto clean up):
208
+ exec_and_close() - will perform the SQL execution and will close the
209
+ Statement object when it's appropriate.
319
210
 
320
- s.execute
321
-
322
- The execute methods for the Statement class, as with all of the execute methods
323
- for the FireRuby library, have three potential return values. They will either
324
- return an Integer, a ResultSet object or nil. A ResultSet object will only be
325
- returned for SQL statements that constitute a query, irrespective of whether
326
- that query returns any data. For all other SQL statements (inserts, updates and
327
- deletes) the execute method will return a count of the number of rows affected
328
- by the statement execution. For any other SQL statements the various execute
329
- methods will return nil.
211
+ exec() - will perform just the SQL execution and will leave the responsibility
212
+ of closing the Statement object to the user.
213
+
214
+ The exec*() methods take two optional arguments:
215
+ parameters - an array of values for the statement parameters,
216
+ this parameter can be nil for statements that don't have parameters.
217
+ Parametrized statements look like this 'SELECT * FROM MY_TABLE WHERE MYID = ?'.
218
+ Note that the SQL select contains a '?'. This is a position
219
+ holder for a value that the statement expects to be provided later. A Statement
220
+ that wraps such a piece of SQL must be provided with the necessary parameters
221
+ to execute properly.
222
+
223
+ transaction - the transaction that defines the scope of the execution,
224
+ if this parameter is nil - the statement is execute in its own transaction.
225
+
226
+ The exec*() methods for the Statement class, as with all of the execute methods
227
+ for the Rubyfb library, have three potential return values. They will either
228
+ return an Integer, a ResultSet object or nil.
229
+ A ResultSet object will only be returned for SQL statements that generate
230
+ output values (like 'select ...', 'select for update ...', 'insert .. returning', 'execute procedure ...'),
231
+ irrespective of whether that query returns any data.
232
+ For insert, update, and delete SQL statements that don't generate output values
233
+ the exec*()/execute() methods will return a count of the number of rows affected by the
234
+ statement execution. For any other SQL statements the return value is nil.
330
235
 
331
236
  A ResultSet object represents a handle by which the data retrieved for a SQL
332
- query can be accessed. While it's possible to obtain a ResultSet from one of the
333
- execute methods on the Connection, Transaction or Statement classes it is more
334
- efficient to create one directly. The constructor for the ResultSet class
335
- accepts the same arguments as the constructor for the Statement class but will
336
- throw an exception if the SQL statement specified is not a query.
337
-
237
+ query can be accessed. The ResultSet objects are obtained from one of the
238
+ exec*()/execute() methods on the Connection, Transaction or Statement objects.
338
239
  Once we have obtained a ResultSet we can extract the rows of data for a query
339
240
  from it. To fetch a row of data from a ResultSet object you call the fetch
340
241
  method, like the following...
@@ -349,9 +250,8 @@ method will be passed the data for the ResultSet, a row at a time.
349
250
  It should be noted that both the Statement and ResultSet objects hold resources
350
251
  while they are active. They both possess close methods and these should be
351
252
  explicitly called to release the associated resources. The exception to this
352
- rule is for ResultSets. If you select all of the rows from a ResultSet then the
353
- resources for the ResultSet are automatically released. It is still safe to call
354
- close on such a ResultSet as this will not cause errors.
253
+ are Statement objects with exec_and_close() called - in this case the statement
254
+ objects are managed internally.
355
255
 
356
256
  Okay, so you've gotten a row of data in the form of a Row object from your
357
257
  ResultSet, how do we get the data out of it? Well, there are a number of ways
@@ -371,7 +271,7 @@ This is beneficial as it frees you from the constraint of knowing the ordering
371
271
  of the columns within the row. For more information of the Row class please
372
272
  consult the API documentation.
373
273
 
374
- That covers the bulk of the SQL classes provided by the FireRuby library. The
274
+ That covers the bulk of the SQL classes provided by the Rubyfb library. The
375
275
  two which haven't been touched upon are the Generator class and the Blob class.
376
276
 
377
277
  The Generator class is a wrapper around the Firebird generator facility. A
@@ -387,15 +287,15 @@ database. Consult the API documentation for further information.
387
287
 
388
288
  === Errors
389
289
 
390
- Whenever a problem occurs within a FireRuby library class then it is likely that
290
+ Whenever a problem occurs within a Rubyfb library class then it is likely that
391
291
  a FireRubyException will be thrown. The FireRubyException class is the error
392
- class used by the FireRuby library whenever it hits trouble. The class provides
292
+ class used by the Rubyfb library whenever it hits trouble. The class provides
393
293
  a means of finding out a little more about what exactly has gone wrong. Again,
394
294
  consult the API documentation for more details.
395
295
 
396
296
  === Firebird Service Manager
397
297
 
398
- The FireRuby library provides a set of class that provide for an interaction
298
+ The Rubyfb library provides a set of class that provide for an interaction
399
299
  with the Firebird service manager. This interaction allows for the execution of
400
300
  tasks, such as the backing up of a database, on the database server. To execute
401
301
  such tasks against the service manager for a Firebird instance you first need
@@ -408,7 +308,7 @@ the host name of the server running the Firebird instance. In the example above
408
308
  this would be a local machine but could be any machine that can be reached over
409
309
  the network (NOTE: although Firebird supports a number of underlying transport
410
310
  protocols in accessing a service manager currently only TCP/IP is supported for
411
- the FireRuby library).
311
+ the Rubyfb library).
412
312
 
413
313
  The next step in executing service manager tasks involves connecting your
414
314
  ServiceManager object to the service manager for a Firebird instance. To do this
@@ -420,7 +320,7 @@ database administrator you might do the following...
420
320
  sm.connect('sysdba', 'masterkey')
421
321
 
422
322
  Assuming that this succeeds you are now ready to execute tasks through your
423
- ServiceManager object. Within the FireRuby library individual task are broken
323
+ ServiceManager object. Within the Rubyfb library individual task are broken
424
324
  out into separate classes. For this release (0.4.1) there are four task classes
425
325
  provided in the library - Backup, Restore, AddUser and RemoveUser. I think the
426
326
  class names are relatively self explanatory but if you want more information
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'echoe'
2
- e = Echoe.new('rubyfb', '0.5.9') do |p|
2
+ e = Echoe.new('rubyfb', '0.6') do |p|
3
3
  p.description = "Firebird SQL access library"
4
4
  p.url = "http://rubyforge.org/projects/rubyfb"
5
5
  p.author = "George Georgiev"
data/ext/Blob.c CHANGED
@@ -166,7 +166,7 @@ static VALUE eachBlobSegment(VALUE self) {
166
166
  Data_Get_Struct(self, BlobHandle, blob);
167
167
  segment = loadBlobSegment(blob, &size);
168
168
  while(segment != NULL) {
169
- result = rb_yield(rfbstr(connection, blob->charset, segment, size));
169
+ result = rb_yield(rb_str_new(segment, size));
170
170
  free(segment);
171
171
  segment = loadBlobSegment(blob, &size);
172
172
  }