ibruby 0.5.0-i586-linux

Sign up to get free protection for your applications and to get access to all the features.
data/doc/README ADDED
@@ -0,0 +1,456 @@
1
+ = FireRuby Version 0.4.1
2
+ FireRuby is an extension for the Ruby programming language that provides access
3
+ to the Firebird open source RDBMS. The FireRuby library is release under the
4
+ Mozilla Public Licence version 1.1 and is free for commercial use.
5
+
6
+ ---
7
+
8
+ == Enhancements & Alterations
9
+
10
+ This release has been brought about as a direct result of efforts to get the
11
+ library working on a 64 bit platform. This process exposed some code of
12
+ questionable quality. All of the issues raised in getting a 64 bit build have
13
+ been addressed and it's only fair that the improvements obtained be passed on
14
+ to all platforms. Functionally nothing has changed since the last release and
15
+ the new version should replace the old with no problems.
16
+
17
+ === Bug Fixes
18
+
19
+ A number of bug fixes were implemented as part of the effort to get the library
20
+ working on a 64 bit platform. None of these had been raised as bugs against the
21
+ library so I have nothing specific to tick off.
22
+
23
+ === Backward Compatibility
24
+
25
+ Version 0.4.0 of the library made fundamental changes to functionality that was
26
+ available in earlier versions of the library. To help accommodate this change
27
+ elements were added to support backward compatibility. The relevant details are
28
+ listed here...
29
+
30
+ - Row objects were switched from keying on column names to keying on column
31
+ aliases. To revert to the older functionality assign a value of true to the
32
+ $FireRubySettings[:ALIAS_KEYS] global setting.
33
+
34
+ - DATE columns were switched from being returned as Time objects to be returned
35
+ as Date objects. To revert to the older functionality assign a value of true
36
+ to the $FireRubySettings[:DATE_AS_DATE] global setting.
37
+
38
+ One other point to note is that, as of version 0.4.0, Enumerable is included in
39
+ the Row and ResultSet classes.
40
+
41
+ === Issues
42
+
43
+ Nothing is perfect so this section outlines those issues that are known to
44
+ exist as of this release.
45
+
46
+ - The service manager functionality does not appear to work on the Mac OS X
47
+ platform. I don't believe that this is a problem in the FireRuby code as I
48
+ have tested the Firebird gbak utility with the -service option and it gives
49
+ the same result. If anyone knows this to be untrue or of a work around let me
50
+ know.
51
+
52
+ - The library currently does not support array columns. This may be implemented
53
+ for a later release depending on demand. No-one has asked for this so far so
54
+ I'm starting to think that people don't make much use of array columns.
55
+
56
+ - The library can be a bit touchy if you don't clean up after yourself. This
57
+ can result in a segmentation violation whenever your program stops if you've
58
+ left a ResultSet or Statement object unclosed. Check through your code to
59
+ insure that this isn't the case before contacting me about problems in this
60
+ line.
61
+
62
+ - The unit tests are currently set up on the assumption that the password for
63
+ your sysdba account is 'masterkey'. If this is not the case, or if you wish
64
+ to use an alternative user for testing, edit the TestSetup.rb file in the
65
+ unit test directory and update the entries there as appropriate. I should also
66
+ note that you may need to alter permissions on the test directory to run the
67
+ actual unit tests on Linux/Unix.
68
+
69
+ ---
70
+
71
+ == Credit Where Credit Is Due
72
+
73
+ Over its lifetime the FireRuby library has benefitted from input provided by a
74
+ number of individuals. This section acknowledges these inputs...
75
+
76
+ <b>Ken Kunz</b>: Ken has been a strong supporter of the library from early on and
77
+ has contributed through feedback, testing and suggestions. For some time he
78
+ produced and tested the Linux builds of the library.
79
+
80
+ <b>David Walthour</b>: David basically executed all of the work to generate the
81
+ 64 bit version of the library, along the way exposing some flaws in the code
82
+ (amazing what a bit of peer review can find!). David produced the 64 bit version
83
+ of the library gem.
84
+
85
+ <b>John Wood</b>: John currently builds and tests the Mac OS X version of the
86
+ library.
87
+
88
+ <b>Art Federov</b>: Art provided input on handling and testing character sets.
89
+
90
+ ---
91
+
92
+ == Installation & Usage
93
+
94
+ The library is provided as a gem and built for use with Ruby 1.8+. Testing
95
+ against an earlier release of Ruby has not been performed. Installation requires
96
+ the Ruby Gems package to be installed. Assuming that these installation criteria
97
+ have been met the library can be installed on Windows by executing a command
98
+ such as the following...
99
+
100
+ gem install fireruby-0.4.1-mswin32.gem
101
+
102
+ On the Mac OS X platform you may require super user privilege if your Ruby is
103
+ installed to the default location (i.e. /usr/local/lib). In this case you can
104
+ use the sudo command to make the installation like this...
105
+
106
+ sudo gem install fireruby-0.4.1-powerpc-darwin.gem
107
+
108
+ Once the gem installation is complete the FireRuby functionality can be accessed
109
+ in code with the usual gem style requires...
110
+
111
+ require 'rubygems'
112
+ require 'fireruby'
113
+
114
+ === Build Details
115
+
116
+ The FireRuby library is a Ruby extension written in C. The avoid build issues
117
+ binary versions are provided for a number of platforms, including...
118
+
119
+ - Windows: Built against a version of Ruby installed using the one-click
120
+ installer and using the freely available Microsoft development tools. This
121
+ version was compiled against version 1.5.2 of Firebird.
122
+
123
+ - Linux: Built on Ubuntu Linux (Breezy Badger) using a version of Ruby 1.8.2
124
+ installed via the Synaptic package manager. This package manager was also
125
+ used to make an installation of Firebird.
126
+
127
+ - Mac OS X: Build on version 10.4.3 of OS X against the 1.8.2 version of Ruby
128
+ that comes with the operating system. A framework installation of Firebird
129
+ version 1.5.1 was used to make the build.
130
+
131
+ Its possible to try and build the library on other platforms so I'll provide a
132
+ few details as to how to go about doing this. The first step is to download the
133
+ CVS tar ball from the Ruby Forge site and expand it into a local directory. This
134
+ will create a directory called fireruby. Change into this directory and then
135
+ into the fireruby/src subdirectory.
136
+
137
+ This directory contains a file called extconf.rb that is used to create the
138
+ make file used to build the library. The make file is created by executing this
139
+ file but before you do there are a number of parameters that you should be
140
+ aware of. The main one of these is --with-firebird-dir. This parameter is used
141
+ to indicate the whereabouts of the Firebird headers and libraries. The following
142
+ is an example of how this might be used...
143
+
144
+ ruby extconf.rb --with-firebird-dir=/usr/local/firebird
145
+
146
+ You may need to customise the path for your own Firebird installation. The path
147
+ specified should be a directory that contains subdirectories called 'lib' and
148
+ 'include'. The lib subdirectory should contain the fbclient shared library and
149
+ include should contain the ibase.h header file.
150
+
151
+ A note for Windows users. The library requires the free Microsoft C++ compiler,
152
+ the Windows SDK, the .NET SDK and nmake to build. If you have all of these
153
+ and Firebird installed to default locations then you can create a make file
154
+ using the mkmf.bat batch file in the src directory.
155
+
156
+ Once you have the make file you can attempt a library build using either make
157
+ (on Unix/Linux) or nmake (on Windows). If it builds successfully you can move
158
+ on to creating a gem file for installation. To do this, change into the ../gem
159
+ directory. In this directory you can do the following (on Windows)...
160
+
161
+ make_gem
162
+
163
+ ...or the following (on Unix/Linux)...
164
+
165
+ ruby make_gem.rb
166
+
167
+ This will create the gem file in the main fireruby directory. Install this and
168
+ execute the unit tests to check whether you're version is working.
169
+
170
+ === So How Do I Use It?
171
+
172
+ This section will provide some examples of usage for the the FireRuby classes.
173
+ Throughout the code the following set of assumptions are made.
174
+
175
+ - The user name and password that will be employed to attach to the database
176
+ are 'sysdba' and 'masterkey' respectively (the Firebird defaults).
177
+
178
+ - The databases attached to will all be local (i.e. they will all reside on the
179
+ same machine) as the test code.
180
+
181
+ A database, from the Firebird perspective, is made up of one or more files. From
182
+ a FireRuby perspective a user interaction with a database starts through the
183
+ Database class. This class provides facilities that allow for creating, dropping
184
+ and connecting to database instances. For example, to obtain a connection to a
185
+ database you would use something like the following...
186
+
187
+ require 'rubygems'
188
+ require 'fireruby'
189
+
190
+ include FireRuby
191
+
192
+ db = Database.new('./test.fdb')
193
+ c = db.connect('sysdba', 'masterkey')
194
+
195
+ This example starts by requiring the necessary files and including the FireRuby
196
+ module locally - later examples will not detail these lines but they are always
197
+ required to use the FireRuby code.
198
+
199
+ The first line of code after the include creates a new database object. This
200
+ process does not actually create the database file (see the Database#create
201
+ method API documentation if that is what you want to do), it simple creates an
202
+ abstract reference to a database. In creating the Database object we had to
203
+ provide a database specification string which identifies the database we want to
204
+ access. In this case we are specifying a database in the current working
205
+ directory called 'test.fdb'. See the Firebird documentation for details on the
206
+ structure of more complex database specifications.
207
+
208
+ The last line of code in the example given above opens a connection to the
209
+ database. In doing this we had to provide two parameters, the database user
210
+ name and password. These are required to gain access to the database.
211
+
212
+ A connection represents a conduit to a database and obtaining a connection is a
213
+ prerequisite to working with the database. The FireRuby library support having
214
+ multiple connections, to one or more databases, using one or more users, active
215
+ simultaneously. FireRuby represents a database connection through objects of the
216
+ Connection class. This class provides functionality to determine the current
217
+ state a database connection (open or closed) and for closing the connection.
218
+ Connections take up resources, both locally and on the database server and
219
+ should be explicitly closed when they are no longer required.
220
+
221
+ The connection class also provides a set of conveniences methods to allow for
222
+ the execution of SQL against a database. These methods, execute_immediate and
223
+ execute, represently two slightly different approaches to executing SQL against
224
+ the database. Refer to the API documentation for more information.
225
+
226
+ An advantage of using a relational database management system like Firebird is
227
+ that it provides transactions. A transaction represents a block of work that is
228
+ either all completed successful or none of it is applied. From the perspective
229
+ of the database this means that a series of steps that make changes to the
230
+ tables in the database can be wrapped in a transaction to insure that they
231
+ either all complete or that none of the changes are applied.
232
+
233
+ The FireRuby library represents a database transaction through instances of the
234
+ Transaction class. There are two ways of obtaining a Transaction using the
235
+ library, both requiring you to have an open database connection. The first way
236
+ is to construct a new Transaction object like so...
237
+
238
+ tx = Transaction.new(connection)
239
+
240
+ The Transaction constructor takes a single parameter which must be either a
241
+ Connection object or an array of Connection objects. If you pass an array of
242
+ Connection objects to this constructor then the Transaction created will apply
243
+ across all of the databases that the connections refer to, allowing you to
244
+ have transactional control of work that must utilise more than one database. The
245
+ second way to obtain a transaction is to simply request one from a Connection
246
+ object, like so.
247
+
248
+ tx = connection.start_transaction
249
+
250
+ In this case the transaction will only ever apply to one database, the one that
251
+ the connection relates to. This method also accepts a block, taking a single
252
+ parameter. The parameter passed to the block will be the transaction created.
253
+ In this case the lifetime of the transaction is delimited by the block. If the
254
+ block completes successfully then the work of the transaction will be committed
255
+ to the database. If the block raises an exception then the transactional work
256
+ will be rolled back.
257
+
258
+ When the block of work associated with a transaction is complete the user must
259
+ instruct the system to either apply the changes implemented by the work or to
260
+ discard them. This can be done by calling the commit or rollback methods of the
261
+ Transaction class respectively. Once a transaction has been committed or rolled
262
+ back it can no longer be used and should be discarded. Note that attempts to
263
+ close a connection that has an active transaction against it will fail, so one
264
+ of the commit or rollback methods should be explictly called in code. The
265
+ block technique detailed above helps protect against the failure to do this and
266
+ is a useful technique.
267
+
268
+ The Transaction object provides a number of other informational and utility
269
+ methods. Check the API documentation for this class for more information.
270
+
271
+ So we've looked at connections and transactions, but how do we actually do
272
+ something practical with the database. Well there are a number of possible
273
+ approaches that we can take to this. Both the Connection and Transaction classes
274
+ have convenience method for the execution of SQL statements and these are useful
275
+ for quick SQL. Where you want something that you can repeatedly reuse and,
276
+ optionally, pass parameters to then you need the Statement class.
277
+
278
+ The Statement class represents a SQL statement that has been validated and
279
+ prepared for execution. Here's an example of creating a SQL statement...
280
+
281
+ s = Statement.new(cxn, tx, 'SELECT * FROM MY_TABLE', 3)
282
+
283
+ In this example we have created a Statement object that wraps a SQL select from
284
+ a table called MY_TABLE. The first parameter to the constructor is a Connection
285
+ object and the second is a Transaction, both mandatory. You may be thinking
286
+ 'why do I need a transaction here, I'm not changing anything?'. This is true
287
+ (well sort of) but it's a requirement of the underlying database system. This
288
+ is also the case for the final parameter to the constructor. The value 3 is
289
+ the SQL dialect to be used with the Statement. This exists for reason arising
290
+ from the move from closed source Interbase to open source Firebird. The
291
+ parameter should be given a value of between 1 and 3. If you're not sure what
292
+ this is and you're only using Firebird it's probably safe to use a value of
293
+ 3 here. Other values are for backward compatibility. Consult the Firebird and
294
+ Interbase documentation for more details.
295
+
296
+ Anyway, now that we have our Statement how do we use it? Well, the answer is
297
+ that we call once of the Statement objects execute methods. The one to be called
298
+ depends on whether the Statement requires parameters or not. What are parameters
299
+ you ask? Well, look at the following...
300
+
301
+ s = Statement.new(cxn, tx, 'SELECT * FROM MY_TABLE WHERE MYID = ?', 3)
302
+
303
+ Note that the SQL select for this Statement contains a '?'. This is a position
304
+ holder for a value that the statement expects to be provided later. A Statement
305
+ that wraps such a piece of SQL must be provided with the necessary parameters
306
+ to execute properly. Where a Statement object represents SQL that requires a
307
+ parameter then the execute_for method must be called, like this...
308
+
309
+ s.execute_for([25])
310
+
311
+ This code executes the SQL substituting the parameters from the array of data
312
+ passed to the function call. If a Statement object represents SQL that does not
313
+ require parameter values a call to the execute method will suffice, such as the
314
+ following...
315
+
316
+ s.execute
317
+
318
+ The execute methods for the Statement class, as with all of the execute methods
319
+ for the FireRuby library, have three potential return values. They will either
320
+ return an Integer, a ResultSet object or nil. A ResultSet object will only be
321
+ returned for SQL statements that constitute a query, irrespective of whether
322
+ that query returns any data. For all other SQL statements (inserts, updates and
323
+ deletes) the execute method will return a count of the number of rows affected
324
+ by the statement execution. For any other SQL statements the various execute
325
+ methods will return nil.
326
+
327
+ A ResultSet object represents a handle by which the data retrieved for a SQL
328
+ query can be accessed. While it's possible to obtain a ResultSet from one of the
329
+ execute methods on the Connection, Transaction or Statement classes it is more
330
+ efficient to create one directly. The constructor for the ResultSet class
331
+ accepts the same arguments as the constructor for the Statement class but will
332
+ throw an exception if the SQL statement specified is not a query.
333
+
334
+ Once we have obtained a ResultSet we can extract the rows of data for a query
335
+ from it. To fetch a row of data from a ResultSet object you call the fetch
336
+ method, like the following...
337
+
338
+ row = r.fetch
339
+
340
+ This fetches a single row of data for a query represented as a Row object (which
341
+ will be covered shortly). The ResultSet class also provides for iteration across
342
+ the contents of a result set by providing an each method. The block to the each
343
+ method will be passed the data for the ResultSet, a row at a time.
344
+
345
+ It should be noted that both the Statement and ResultSet objects hold resources
346
+ while they are active. They both possess close methods and these should be
347
+ explicitly called to release the associated resources. The exception to this
348
+ rule is for ResultSets. If you select all of the rows from a ResultSet then the
349
+ resources for the ResultSet are automatically released. It is still safe to call
350
+ close on such a ResultSet as this will not cause errors.
351
+
352
+ Okay, so you've gotten a row of data in the form of a Row object from your
353
+ ResultSet, how do we get the data out of it? Well, there are a number of ways
354
+ of doing this. You can treat the Row object like an array and dereference the
355
+ columns of data within the row like this...
356
+
357
+ value = row[1]
358
+
359
+ The index specified to the array dereference operator specifies the column that
360
+ you want the data for. Column indices start at 0. Alternatively you can treat
361
+ the Row object like a read only Hash object and use the column name to access
362
+ the data, like this...
363
+
364
+ value = row['MYID']
365
+
366
+ This is beneficial as it frees you from the constraint of knowing the ordering
367
+ of the columns within the row. For more information of the Row class please
368
+ consult the API documentation.
369
+
370
+ That covers the bulk of the SQL classes provided by the FireRuby library. The
371
+ two which haven't been touched upon are the Generator class and the Blob class.
372
+
373
+ The Generator class is a wrapper around the Firebird generator facility. A
374
+ generator, also known as a sequence, provides a means of creating a list of
375
+ numeric values in a way that is guaranteed to be thread and process safe. Used
376
+ properly generators can be employed to create unique sequences that make perfect
377
+ table keys. Consult the API documentation for more details on the Generator
378
+ class.
379
+
380
+ The Blob class is returned as part of the Row object data obtained from a
381
+ ResultSet. The class wraps the concept of a binary large object stored in the
382
+ database. Consult the API documentation for further information.
383
+
384
+ === Errors
385
+
386
+ Whenever a problem occurs within a FireRuby library class then it is likely that
387
+ a FireRubyException will be thrown. The FireRubyException class is the error
388
+ class used by the FireRuby library whenever it hits trouble. The class provides
389
+ a means of finding out a little more about what exactly has gone wrong. Again,
390
+ consult the API documentation for more details.
391
+
392
+ === Firebird Service Manager
393
+
394
+ The FireRuby library provides a set of class that provide for an interaction
395
+ with the Firebird service manager. This interaction allows for the execution of
396
+ tasks, such as the backing up of a database, on the database server. To execute
397
+ such tasks against the service manager for a Firebird instance you first need
398
+ to obtain a ServiceManager class instance. This can be done as follows...
399
+
400
+ sm = ServiceManager.new('localhost')
401
+
402
+ The constructor for the ServiceManager class takes a single parameter that is
403
+ the host name of the server running the Firebird instance. In the example above
404
+ this would be a local machine but could be any machine that can be reached over
405
+ the network (NOTE: although Firebird supports a number of underlying transport
406
+ protocols in accessing a service manager currently only TCP/IP is supported for
407
+ the FireRuby library).
408
+
409
+ The next step in executing service manager tasks involves connecting your
410
+ ServiceManager object to the service manager for a Firebird instance. To do this
411
+ you must supply a user name and password. The user name and password used must
412
+ be a user that exists on the Firebird instance. The user you connect as can
413
+ affect the access to services that you receive. For example, to connect as the
414
+ database administrator you might do the following...
415
+
416
+ sm.connect('sysdba', 'masterkey')
417
+
418
+ Assuming that this succeeds you are now ready to execute tasks through your
419
+ ServiceManager object. Within the FireRuby library individual task are broken
420
+ out into separate classes. For this release (0.4.1) there are four task classes
421
+ provided in the library - Backup, Restore, AddUser and RemoveUser. I think the
422
+ class names are relatively self explanatory but if you want more information
423
+ consult the API documentation for a class.
424
+
425
+ To use the task classes you construct a class instance, configure it as you may
426
+ need and then execute it. Here's an example of going through this procedure to
427
+ create a database backup...
428
+
429
+ b = Backup.new('c:\database\work.fdb', 'c:\temp\work.bak')
430
+ b.metadata_only = true
431
+ b.execute(sm)
432
+
433
+ The first list creates the new Backup object. The first parameter passed to this
434
+ call is the path and name of the primary file of the database to be backed up
435
+ (NOTE: All paths are relative to the database server). The second parameter is
436
+ the path and name of the database backup file to be created. The second line
437
+ sets an attribute on the class to indicate that only the metadata (i.e. it's
438
+ schema but not it's data) for the specified database should be included in the
439
+ backup. The final line begins the execution of the backup task on the database
440
+ server. This will block until completion.
441
+
442
+ Its also possible to execute a batch of tasks against a service manager. To do
443
+ this you would accumulate the tasks to be executed and then pass them all at the
444
+ same time to the ServiceManager#execute method, like so...
445
+
446
+ t = Array.new
447
+ t.push(Backup.new('c:\database\work.fdb', 'c:\temp\work.bak'))
448
+ ...
449
+ # Create more tasks here and add them to the array.
450
+
451
+ sm.execute(*t)
452
+
453
+ The tasks will be executed in the order they are specified to the ServiceManager
454
+ object. For the example above this would mean in the order they were added to
455
+ the array. For more details on the ServiceManager class and the various task
456
+ classes please consult the API documentation.