rubyfb 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/CHANGELOG +6 -0
  2. data/LICENSE +411 -0
  3. data/Manifest +73 -0
  4. data/README +460 -0
  5. data/Rakefile +20 -0
  6. data/examples/example01.rb +65 -0
  7. data/ext/AddUser.c +464 -0
  8. data/ext/AddUser.h +37 -0
  9. data/ext/Backup.c +783 -0
  10. data/ext/Backup.h +37 -0
  11. data/ext/Blob.c +421 -0
  12. data/ext/Blob.h +65 -0
  13. data/ext/Common.c +54 -0
  14. data/ext/Common.h +37 -0
  15. data/ext/Connection.c +863 -0
  16. data/ext/Connection.h +50 -0
  17. data/ext/DataArea.c +274 -0
  18. data/ext/DataArea.h +38 -0
  19. data/ext/Database.c +449 -0
  20. data/ext/Database.h +48 -0
  21. data/ext/FireRuby.c +240 -0
  22. data/ext/FireRuby.h +50 -0
  23. data/ext/FireRubyException.c +268 -0
  24. data/ext/FireRubyException.h +51 -0
  25. data/ext/Generator.c +689 -0
  26. data/ext/Generator.h +53 -0
  27. data/ext/RemoveUser.c +212 -0
  28. data/ext/RemoveUser.h +37 -0
  29. data/ext/Restore.c +855 -0
  30. data/ext/Restore.h +37 -0
  31. data/ext/ResultSet.c +809 -0
  32. data/ext/ResultSet.h +60 -0
  33. data/ext/Row.c +965 -0
  34. data/ext/Row.h +55 -0
  35. data/ext/ServiceManager.c +316 -0
  36. data/ext/ServiceManager.h +48 -0
  37. data/ext/Services.c +124 -0
  38. data/ext/Services.h +42 -0
  39. data/ext/Statement.c +785 -0
  40. data/ext/Statement.h +62 -0
  41. data/ext/Transaction.c +684 -0
  42. data/ext/Transaction.h +50 -0
  43. data/ext/TypeMap.c +1182 -0
  44. data/ext/TypeMap.h +51 -0
  45. data/ext/extconf.rb +28 -0
  46. data/ext/mkmf.bat +1 -0
  47. data/lib/SQLType.rb +224 -0
  48. data/lib/active_record/connection_adapters/rubyfb_adapter.rb +805 -0
  49. data/lib/mkdoc +1 -0
  50. data/lib/rubyfb.rb +2 -0
  51. data/lib/rubyfb_lib.so +0 -0
  52. data/lib/src.rb +1800 -0
  53. data/rubyfb.gemspec +31 -0
  54. data/test/AddRemoveUserTest.rb +56 -0
  55. data/test/BackupRestoreTest.rb +99 -0
  56. data/test/BlobTest.rb +57 -0
  57. data/test/CharacterSetTest.rb +63 -0
  58. data/test/ConnectionTest.rb +111 -0
  59. data/test/DDLTest.rb +54 -0
  60. data/test/DatabaseTest.rb +83 -0
  61. data/test/GeneratorTest.rb +50 -0
  62. data/test/KeyTest.rb +140 -0
  63. data/test/ResultSetTest.rb +162 -0
  64. data/test/RoleTest.rb +73 -0
  65. data/test/RowCountTest.rb +65 -0
  66. data/test/RowTest.rb +203 -0
  67. data/test/SQLTest.rb +182 -0
  68. data/test/SQLTypeTest.rb +101 -0
  69. data/test/ServiceManagerTest.rb +29 -0
  70. data/test/StatementTest.rb +135 -0
  71. data/test/TestSetup.rb +11 -0
  72. data/test/TransactionTest.rb +112 -0
  73. data/test/TypeTest.rb +92 -0
  74. data/test/UnitTest.rb +65 -0
  75. metadata +149 -0
data/README ADDED
@@ -0,0 +1,460 @@
1
+ v0.5.1 =
2
+ Initial rubyfb release
3
+ To use rubyfb adapter in RoR set your database adpter to "rubyfb"
4
+
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.
9
+
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
28
+
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...
33
+
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.
44
+
45
+ === Issues
46
+
47
+ Nothing is perfect so this section outlines those issues that are known to
48
+ exist as of this release.
49
+
50
+ - 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
52
+ have tested the Firebird gbak utility with the -service option and it gives
53
+ the same result. If anyone knows this to be untrue or of a work around let me
54
+ know.
55
+
56
+ - The library currently does not support array columns. This may be implemented
57
+ for a later release depending on demand. No-one has asked for this so far so
58
+ I'm starting to think that people don't make much use of array columns.
59
+
60
+ - The library can be a bit touchy if you don't clean up after yourself. This
61
+ can result in a segmentation violation whenever your program stops if you've
62
+ left a ResultSet or Statement object unclosed. Check through your code to
63
+ insure that this isn't the case before contacting me about problems in this
64
+ line.
65
+
66
+ - The unit tests are currently set up on the assumption that the password for
67
+ your sysdba account is 'masterkey'. If this is not the case, or if you wish
68
+ to use an alternative user for testing, edit the TestSetup.rb file in the
69
+ unit test directory and update the entries there as appropriate. I should also
70
+ note that you may need to alter permissions on the test directory to run the
71
+ actual unit tests on Linux/Unix.
72
+
73
+ ---
74
+
75
+ == Credit Where Credit Is Due
76
+
77
+ Over its lifetime the FireRuby library has benefitted from input provided by a
78
+ number of individuals. This section acknowledges these inputs...
79
+
80
+ <b>Ken Kunz</b>: Ken has been a strong supporter of the library from early on and
81
+ has contributed through feedback, testing and suggestions. For some time he
82
+ produced and tested the Linux builds of the library.
83
+
84
+ <b>David Walthour</b>: David basically executed all of the work to generate the
85
+ 64 bit version of the library, along the way exposing some flaws in the code
86
+ (amazing what a bit of peer review can find!). David produced the 64 bit version
87
+ of the library gem.
88
+
89
+ <b>John Wood</b>: John currently builds and tests the Mac OS X version of the
90
+ library.
91
+
92
+ <b>Art Federov</b>: Art provided input on handling and testing character sets.
93
+
94
+ ---
95
+
96
+ == Installation & Usage
97
+
98
+ The library is provided as a gem and built for use with Ruby 1.8+. Testing
99
+ against an earlier release of Ruby has not been performed. Installation requires
100
+ 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
102
+ such as the following...
103
+
104
+ gem install fireruby-0.4.1-mswin32.gem
105
+
106
+ On the Mac OS X platform you may require super user privilege if your Ruby is
107
+ installed to the default location (i.e. /usr/local/lib). In this case you can
108
+ use the sudo command to make the installation like this...
109
+
110
+ sudo gem install fireruby-0.4.1-powerpc-darwin.gem
111
+
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
119
+
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...
122
+
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.
130
+
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?
175
+
176
+ This section will provide some examples of usage for the the FireRuby classes.
177
+ Throughout the code the following set of assumptions are made.
178
+
179
+ - The user name and password that will be employed to attach to the database
180
+ are 'sysdba' and 'masterkey' respectively (the Firebird defaults).
181
+
182
+ - The databases attached to will all be local (i.e. they will all reside on the
183
+ same machine) as the test code.
184
+
185
+ 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
187
+ Database class. This class provides facilities that allow for creating, dropping
188
+ and connecting to database instances. For example, to obtain a connection to a
189
+ database you would use something like the following...
190
+
191
+ require 'rubygems'
192
+ require 'fireruby'
193
+
194
+ include FireRuby
195
+
196
+ db = Database.new('./test.fdb')
197
+ c = db.connect('sysdba', 'masterkey')
198
+
199
+ This example starts by requiring the necessary files and including the FireRuby
200
+ module locally - later examples will not detail these lines but they are always
201
+ required to use the FireRuby code.
202
+
203
+ The first line of code after the include creates a new database object. This
204
+ process does not actually create the database file (see the Database#create
205
+ method API documentation if that is what you want to do), it simple creates an
206
+ abstract reference to a database. In creating the Database object we had to
207
+ provide a database specification string which identifies the database we want to
208
+ access. In this case we are specifying a database in the current working
209
+ directory called 'test.fdb'. See the Firebird documentation for details on the
210
+ structure of more complex database specifications.
211
+
212
+ The last line of code in the example given above opens a connection to the
213
+ database. In doing this we had to provide two parameters, the database user
214
+ name and password. These are required to gain access to the database.
215
+
216
+ 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
218
+ multiple connections, to one or more databases, using one or more users, active
219
+ simultaneously. FireRuby represents a database connection through objects of the
220
+ Connection class. This class provides functionality to determine the current
221
+ state a database connection (open or closed) and for closing the connection.
222
+ Connections take up resources, both locally and on the database server and
223
+ should be explicitly closed when they are no longer required.
224
+
225
+ The connection class also provides a set of conveniences methods to allow for
226
+ the execution of SQL against a database. These methods, execute_immediate and
227
+ execute, represently two slightly different approaches to executing SQL against
228
+ the database. Refer to the API documentation for more information.
229
+
230
+ An advantage of using a relational database management system like Firebird is
231
+ that it provides transactions. A transaction represents a block of work that is
232
+ either all completed successful or none of it is applied. From the perspective
233
+ of the database this means that a series of steps that make changes to the
234
+ tables in the database can be wrapped in a transaction to insure that they
235
+ either all complete or that none of the changes are applied.
236
+
237
+ The FireRuby library represents a database transaction through instances of the
238
+ Transaction class. There are two ways of obtaining a Transaction using the
239
+ library, both requiring you to have an open database connection. The first way
240
+ is to construct a new Transaction object like so...
241
+
242
+ tx = Transaction.new(connection)
243
+
244
+ The Transaction constructor takes a single parameter which must be either a
245
+ Connection object or an array of Connection objects. If you pass an array of
246
+ Connection objects to this constructor then the Transaction created will apply
247
+ 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
249
+ second way to obtain a transaction is to simply request one from a Connection
250
+ object, like so.
251
+
252
+ tx = connection.start_transaction
253
+
254
+ In this case the transaction will only ever apply to one database, the one that
255
+ the connection relates to. This method also accepts a block, taking a single
256
+ parameter. The parameter passed to the block will be the transaction created.
257
+ In this case the lifetime of the transaction is delimited by the block. If the
258
+ block completes successfully then the work of the transaction will be committed
259
+ to the database. If the block raises an exception then the transactional work
260
+ will be rolled back.
261
+
262
+ When the block of work associated with a transaction is complete the user must
263
+ instruct the system to either apply the changes implemented by the work or to
264
+ discard them. This can be done by calling the commit or rollback methods of the
265
+ Transaction class respectively. Once a transaction has been committed or rolled
266
+ back it can no longer be used and should be discarded. Note that attempts to
267
+ 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
269
+ block technique detailed above helps protect against the failure to do this and
270
+ is a useful technique.
271
+
272
+ The Transaction object provides a number of other informational and utility
273
+ methods. Check the API documentation for this class for more information.
274
+
275
+ So we've looked at connections and transactions, but how do we actually do
276
+ something practical with the database. Well there are a number of possible
277
+ approaches that we can take to this. Both the Connection and Transaction classes
278
+ have convenience method for the execution of SQL statements and these are useful
279
+ for quick SQL. Where you want something that you can repeatedly reuse and,
280
+ optionally, pass parameters to then you need the Statement class.
281
+
282
+ The Statement class represents a SQL statement that has been validated and
283
+ prepared for execution. Here's an example of creating a SQL statement...
284
+
285
+ s = Statement.new(cxn, tx, 'SELECT * FROM MY_TABLE', 3)
286
+
287
+ 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...
312
+
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...
319
+
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.
330
+
331
+ 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
+
338
+ Once we have obtained a ResultSet we can extract the rows of data for a query
339
+ from it. To fetch a row of data from a ResultSet object you call the fetch
340
+ method, like the following...
341
+
342
+ row = r.fetch
343
+
344
+ This fetches a single row of data for a query represented as a Row object (which
345
+ will be covered shortly). The ResultSet class also provides for iteration across
346
+ the contents of a result set by providing an each method. The block to the each
347
+ method will be passed the data for the ResultSet, a row at a time.
348
+
349
+ It should be noted that both the Statement and ResultSet objects hold resources
350
+ while they are active. They both possess close methods and these should be
351
+ 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.
355
+
356
+ Okay, so you've gotten a row of data in the form of a Row object from your
357
+ ResultSet, how do we get the data out of it? Well, there are a number of ways
358
+ of doing this. You can treat the Row object like an array and dereference the
359
+ columns of data within the row like this...
360
+
361
+ value = row[1]
362
+
363
+ The index specified to the array dereference operator specifies the column that
364
+ you want the data for. Column indices start at 0. Alternatively you can treat
365
+ the Row object like a read only Hash object and use the column name to access
366
+ the data, like this...
367
+
368
+ value = row['MYID']
369
+
370
+ This is beneficial as it frees you from the constraint of knowing the ordering
371
+ of the columns within the row. For more information of the Row class please
372
+ consult the API documentation.
373
+
374
+ That covers the bulk of the SQL classes provided by the FireRuby library. The
375
+ two which haven't been touched upon are the Generator class and the Blob class.
376
+
377
+ The Generator class is a wrapper around the Firebird generator facility. A
378
+ generator, also known as a sequence, provides a means of creating a list of
379
+ numeric values in a way that is guaranteed to be thread and process safe. Used
380
+ properly generators can be employed to create unique sequences that make perfect
381
+ table keys. Consult the API documentation for more details on the Generator
382
+ class.
383
+
384
+ The Blob class is returned as part of the Row object data obtained from a
385
+ ResultSet. The class wraps the concept of a binary large object stored in the
386
+ database. Consult the API documentation for further information.
387
+
388
+ === Errors
389
+
390
+ Whenever a problem occurs within a FireRuby library class then it is likely that
391
+ 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
393
+ a means of finding out a little more about what exactly has gone wrong. Again,
394
+ consult the API documentation for more details.
395
+
396
+ === Firebird Service Manager
397
+
398
+ The FireRuby library provides a set of class that provide for an interaction
399
+ with the Firebird service manager. This interaction allows for the execution of
400
+ tasks, such as the backing up of a database, on the database server. To execute
401
+ such tasks against the service manager for a Firebird instance you first need
402
+ to obtain a ServiceManager class instance. This can be done as follows...
403
+
404
+ sm = ServiceManager.new('localhost')
405
+
406
+ The constructor for the ServiceManager class takes a single parameter that is
407
+ the host name of the server running the Firebird instance. In the example above
408
+ this would be a local machine but could be any machine that can be reached over
409
+ the network (NOTE: although Firebird supports a number of underlying transport
410
+ protocols in accessing a service manager currently only TCP/IP is supported for
411
+ the FireRuby library).
412
+
413
+ The next step in executing service manager tasks involves connecting your
414
+ ServiceManager object to the service manager for a Firebird instance. To do this
415
+ you must supply a user name and password. The user name and password used must
416
+ be a user that exists on the Firebird instance. The user you connect as can
417
+ affect the access to services that you receive. For example, to connect as the
418
+ database administrator you might do the following...
419
+
420
+ sm.connect('sysdba', 'masterkey')
421
+
422
+ Assuming that this succeeds you are now ready to execute tasks through your
423
+ ServiceManager object. Within the FireRuby library individual task are broken
424
+ out into separate classes. For this release (0.4.1) there are four task classes
425
+ provided in the library - Backup, Restore, AddUser and RemoveUser. I think the
426
+ class names are relatively self explanatory but if you want more information
427
+ consult the API documentation for a class.
428
+
429
+ To use the task classes you construct a class instance, configure it as you may
430
+ need and then execute it. Here's an example of going through this procedure to
431
+ create a database backup...
432
+
433
+ b = Backup.new('c:\database\work.fdb', 'c:\temp\work.bak')
434
+ b.metadata_only = true
435
+ b.execute(sm)
436
+
437
+ The first list creates the new Backup object. The first parameter passed to this
438
+ call is the path and name of the primary file of the database to be backed up
439
+ (NOTE: All paths are relative to the database server). The second parameter is
440
+ the path and name of the database backup file to be created. The second line
441
+ sets an attribute on the class to indicate that only the metadata (i.e. it's
442
+ schema but not it's data) for the specified database should be included in the
443
+ backup. The final line begins the execution of the backup task on the database
444
+ server. This will block until completion.
445
+
446
+ Its also possible to execute a batch of tasks against a service manager. To do
447
+ this you would accumulate the tasks to be executed and then pass them all at the
448
+ same time to the ServiceManager#execute method, like so...
449
+
450
+ t = Array.new
451
+ t.push(Backup.new('c:\database\work.fdb', 'c:\temp\work.bak'))
452
+ ...
453
+ # Create more tasks here and add them to the array.
454
+
455
+ sm.execute(*t)
456
+
457
+ The tasks will be executed in the order they are specified to the ServiceManager
458
+ object. For the example above this would mean in the order they were added to
459
+ the array. For more details on the ServiceManager class and the various task
460
+ classes please consult the API documentation.
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require 'echoe'
2
+ e = Echoe.new('rubyfb', '0.5.2') do |p|
3
+ p.description = "Firebird SQL access library"
4
+ p.url = "http://rubyforge.org/projects/rubyfb"
5
+ p.author = "George Georgiev"
6
+ p.email = "georgiev@heatbs.com"
7
+ p.rdoc_pattern = ["{examples,ext,lib}/*.rb", "CHANGELOG", "README", "LICENSE"]
8
+
9
+ unless (ARGV & ["binpkg", "binrelease"]).empty?
10
+ p.platform=Gem::Platform::CURRENT
11
+ p.eval = Proc.new {
12
+ self.extensions=nil
13
+ self.platform=Gem::Platform::CURRENT
14
+ }
15
+ end
16
+ end
17
+ e.clean_pattern = e.clean_pattern - e.clean_pattern.grep(/^lib/)
18
+
19
+ task :binpkg => [:compile, :repackage]
20
+ task :binrelease => [:compile, :release]
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require_gem 'fireruby'
5
+
6
+ include FireRuby
7
+
8
+ # Database details constants.
9
+ DB_FILE = "localhost:#{File.expand_path('.')}#{File::SEPARATOR}example.fdb"
10
+ DB_USER_NAME = "sysdba"
11
+ DB_PASSWORD = "masterkey"
12
+
13
+ # SQL constants.
14
+ CREATE_TABLE_SQL = 'CREATE TABLE TESTTABLE (TESTID INTEGER NOT NULL PRIMARY '\
15
+ 'KEY, TESTTEXT VARCHAR(100), TESTFLOAT NUMERIC(6,2), '\
16
+ 'CREATED TIMESTAMP)'
17
+ DROP_TABLE_SQL = 'DROP TABLE TESTTABLE'
18
+ INSERT_SQL = 'INSERT INTO TESTTABLE VALUES(?, ?, ?, ?)'
19
+ SELECT_SQL = 'SELECT * FROM TESTTABLE'
20
+
21
+ begin
22
+ # Check if the database file exists.
23
+ db = nil
24
+ if File.exist?(DB_FILE) == false
25
+ # Create the database file.
26
+ db = Database.create(DB_FILE, DB_USER_NAME, DB_PASSWORD, 1024, 'ASCII')
27
+ else
28
+ # Create the databse object.
29
+ db = Database.new(DB_FILE)
30
+ end
31
+
32
+ # Obtain a connection to the database.
33
+ db.connect(DB_USER_NAME, DB_PASSWORD) do |cxn|
34
+ # Create the database table.
35
+ cxn.execute_immediate(CREATE_TABLE_SQL)
36
+
37
+ # Insert 50 rows into the database.
38
+ decimal = 1.0
39
+ cxn.start_transaction do |tx|
40
+ s = Statement.new(cxn, tx, INSERT_SQL, 3)
41
+ 1.upto(20) do |number|
42
+ s.execute_for([number, "Number is #{number}.", decimal, Time.new])
43
+ decimal = decimal + 0.24
44
+ end
45
+ s.close
46
+ end
47
+
48
+ # Select back the rows inserted and display them
49
+ rows = cxn.execute_immediate(SELECT_SQL)
50
+ rows.each do |row|
51
+ puts "-----"
52
+ puts "Test Id: #{row['TESTID']}"
53
+ puts "Test Text: '#{row['TESTTEXT']}'"
54
+ puts "Test Float: #{row['TESTFLOAT']}"
55
+ puts "Test Created: #{row['CREATED']}"
56
+ puts "-----"
57
+ end
58
+ rows.close
59
+
60
+ # Drop the table.
61
+ cxn.execute_immediate(DROP_TABLE_SQL)
62
+ end
63
+ rescue Excepton => error
64
+ puts error.message
65
+ end