rubyfb 0.5.2-x86-mswin32-60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. data/CHANGELOG +6 -0
  2. data/LICENSE +411 -0
  3. data/Manifest +75 -0
  4. data/README +460 -0
  5. data/Rakefile +21 -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 +810 -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 +30 -0
  46. data/lib/SQLType.rb +224 -0
  47. data/lib/active_record/connection_adapters/rubyfb_adapter.rb +805 -0
  48. data/lib/mkdoc +1 -0
  49. data/lib/rubyfb.rb +2 -0
  50. data/lib/rubyfb_lib.so +0 -0
  51. data/lib/src.rb +1800 -0
  52. data/mswin32fb/fbclient_ms.lib +0 -0
  53. data/mswin32fb/ibase.h +2555 -0
  54. data/mswin32fb/iberror.h +1741 -0
  55. data/rubyfb.gemspec +31 -0
  56. data/test/AddRemoveUserTest.rb +56 -0
  57. data/test/BackupRestoreTest.rb +99 -0
  58. data/test/BlobTest.rb +57 -0
  59. data/test/CharacterSetTest.rb +63 -0
  60. data/test/ConnectionTest.rb +111 -0
  61. data/test/DDLTest.rb +54 -0
  62. data/test/DatabaseTest.rb +83 -0
  63. data/test/GeneratorTest.rb +50 -0
  64. data/test/KeyTest.rb +140 -0
  65. data/test/ResultSetTest.rb +162 -0
  66. data/test/RoleTest.rb +73 -0
  67. data/test/RowCountTest.rb +65 -0
  68. data/test/RowTest.rb +203 -0
  69. data/test/SQLTest.rb +182 -0
  70. data/test/SQLTypeTest.rb +101 -0
  71. data/test/ServiceManagerTest.rb +29 -0
  72. data/test/StatementTest.rb +135 -0
  73. data/test/TestSetup.rb +11 -0
  74. data/test/TransactionTest.rb +112 -0
  75. data/test/TypeTest.rb +92 -0
  76. data/test/UnitTest.rb +65 -0
  77. metadata +143 -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.