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/ext/Connection.h ADDED
@@ -0,0 +1,50 @@
1
+ /*------------------------------------------------------------------------------
2
+ * Connection.h
3
+ *----------------------------------------------------------------------------*/
4
+ /**
5
+ * Copyright � Peter Wood, 2005
6
+ *
7
+ * The contents of this file are subject to the Mozilla Public License Version
8
+ * 1.1 (the "License"); you may not use this file except in compliance with the
9
+ * License. You may obtain a copy of the License at
10
+ *
11
+ * http://www.mozilla.org/MPL/
12
+ *
13
+ * Software distributed under the License is distributed on an "AS IS" basis,
14
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
15
+ * the specificlanguage governing rights and limitations under the License.
16
+ *
17
+ * The Original Code is the FireRuby extension for the Ruby language.
18
+ *
19
+ * The Initial Developer of the Original Code is Peter Wood. All Rights
20
+ * Reserved.
21
+ *
22
+ * @author Peter Wood
23
+ * @version 1.0
24
+ */
25
+ #ifndef FIRERUBY_CONNECTION_H
26
+ #define FIRERUBY_CONNECTION_H
27
+
28
+ /* Includes. */
29
+ #ifndef FIRERUBY_FIRE_RUBY_H
30
+ #include "FireRuby.h"
31
+ #endif
32
+
33
+ #ifndef FIRERUBY_FIRE_RUBY_EXCEPTION_H
34
+ #include "FireRubyException.h"
35
+ #endif
36
+
37
+ /* Structure definitions. */
38
+ typedef struct
39
+ {
40
+ isc_db_handle handle;
41
+ } ConnectionHandle;
42
+
43
+ /* Function prototypes. */
44
+ void Init_Connection(VALUE);
45
+ VALUE rb_connection_new(VALUE, VALUE, VALUE, VALUE);
46
+ void rb_tx_started(VALUE, VALUE);
47
+ void rb_tx_released(VALUE, VALUE);
48
+ void connectionFree(void *);
49
+
50
+ #endif /* FIRERUBY_CONNECTION_H */
data/ext/DataArea.c ADDED
@@ -0,0 +1,274 @@
1
+ /*------------------------------------------------------------------------------
2
+ * DataArea.c
3
+ *----------------------------------------------------------------------------*/
4
+ /**
5
+ * Copyright � Peter Wood, 2005
6
+ *
7
+ * The contents of this file are subject to the Mozilla Public License Version
8
+ * 1.1 (the "License"); you may not use this file except in compliance with the
9
+ * License. You may obtain a copy of the License at
10
+ *
11
+ * http://www.mozilla.org/MPL/
12
+ *
13
+ * Software distributed under the License is distributed on an "AS IS" basis,
14
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
15
+ * the specificlanguage governing rights and limitations under the License.
16
+ *
17
+ * The Original Code is the FireRuby extension for the Ruby language.
18
+ *
19
+ * The Initial Developer of the Original Code is Peter Wood. All Rights
20
+ * Reserved.
21
+ *
22
+ * @author Peter Wood
23
+ * @version 1.0
24
+ */
25
+
26
+ /* Includes. */
27
+ #include "DataArea.h"
28
+ #include "FireRubyException.h"
29
+
30
+ #ifdef OS_UNIX
31
+ #include <inttypes.h>
32
+ #else
33
+ typedef short int16_t;
34
+ typedef long int32_t;
35
+ typedef long long int64_t;
36
+ #endif
37
+
38
+
39
+ /**
40
+ * This function allocates the memory for a output XSQLDA based on a specified
41
+ * XSQLDA providing base details.
42
+ *
43
+ * @param size A count of the number of entries needed in the XSQLDA.
44
+ * @param statement A pointer to the statement handle that will be used in
45
+ * preparing the data area.
46
+ * @param dialect The SQL dialect to be used in preparing the data area.
47
+ *
48
+ * @return A pointer to the newly allocated XSQLDA.
49
+ *
50
+ */
51
+ XSQLDA *allocateOutXSQLDA(int size, isc_stmt_handle *statement, short dialect)
52
+ {
53
+ XSQLDA *area = (XSQLDA *)ALLOC_N(char, XSQLDA_LENGTH(size));
54
+
55
+ if(area != NULL)
56
+ {
57
+ ISC_STATUS status[20];
58
+
59
+ area->sqln = size;
60
+ area->version = SQLDA_VERSION1;
61
+ if(isc_dsql_describe(status, statement, dialect, area) != 0)
62
+ {
63
+ /* Release the memory and generate an error. */
64
+ free(area);
65
+ rb_fireruby_raise(status, "Error allocating output storage space.");
66
+ }
67
+ }
68
+ else
69
+ {
70
+ /* Generate an error. */
71
+ rb_raise(rb_eNoMemError,
72
+ "Memory allocation failure preparing output SQL data "\
73
+ "definition area.");
74
+ }
75
+
76
+ return(area);
77
+ }
78
+
79
+
80
+ /**
81
+ * This function allocates the memory for a input XSQLDA based on a specified
82
+ * XSQLDA providing base details.
83
+ *
84
+ * @param size A count of the number of entries needed in the XSQLDA.
85
+ * @param statement A pointer to the statement handle that will be used in
86
+ * preparing the data area.
87
+ * @param dialect The SQL dialect to be used in preparing the data area.
88
+ *
89
+ * @return A pointer to the newly allocated XSQLDA.
90
+ *
91
+ */
92
+ XSQLDA *allocateInXSQLDA(int size, isc_stmt_handle *statement, short dialect)
93
+ {
94
+ XSQLDA *area = NULL;
95
+
96
+ area = (XSQLDA *)ALLOC_N(char, XSQLDA_LENGTH(size));
97
+
98
+ if(area != NULL)
99
+ {
100
+ ISC_STATUS status[20];
101
+
102
+ area->sqln = size;
103
+ area->version = SQLDA_VERSION1;
104
+ if(isc_dsql_describe_bind(status, statement, dialect, area) != 0)
105
+ {
106
+ /* Release the memory and generate an error. */
107
+ free(area);
108
+ rb_fireruby_raise(status, "Error allocating input storage space.");
109
+ }
110
+ }
111
+ else
112
+ {
113
+ /* Generate an error. */
114
+ rb_raise(rb_eNoMemError,
115
+ "Memory allocation failure preparing input SQL data "\
116
+ "definition area.");
117
+ }
118
+
119
+ return(area);
120
+ }
121
+
122
+
123
+ /**
124
+ * This function initializes a previously allocated XSQLDA with space for the
125
+ * data it will contain.
126
+ *
127
+ * @param da A pointer to the XSQLDA to have data space allocated for.
128
+ *
129
+ */
130
+ void prepareDataArea(XSQLDA *da)
131
+ {
132
+ XSQLVAR *field = da->sqlvar;
133
+ int index;
134
+
135
+ for(index = 0; index < da->sqld; index++, field++)
136
+ {
137
+ int type = (field->sqltype & ~1),
138
+ total = (field->sqllen / 2) + 2;
139
+
140
+ field->sqldata = NULL;
141
+ field->sqlind = NULL;
142
+ switch(type)
143
+ {
144
+ case SQL_ARRAY :
145
+ fprintf(stderr, "Allocating for an array (NOT).\n");
146
+ break;
147
+
148
+ case SQL_BLOB :
149
+ field->sqldata = (char *)ALLOC(ISC_QUAD);
150
+ break;
151
+
152
+ case SQL_DOUBLE :
153
+ field->sqldata = (char *)ALLOC(double);
154
+ break;
155
+
156
+ case SQL_FLOAT :
157
+ field->sqldata = (char *)ALLOC(float);
158
+ break;
159
+
160
+ case SQL_INT64 :
161
+ field->sqldata = (char *)ALLOC(int64_t);
162
+ break;
163
+
164
+ case SQL_LONG :
165
+ field->sqldata = (char *)ALLOC(int32_t);
166
+ break;
167
+
168
+ case SQL_SHORT :
169
+ field->sqldata = (char *)ALLOC(int16_t);
170
+ break;
171
+
172
+ case SQL_TEXT :
173
+ field->sqldata = ALLOC_N(char, field->sqllen + 1);
174
+ break;
175
+
176
+ case SQL_TIMESTAMP :
177
+ field->sqldata = (char *)ALLOC(ISC_TIMESTAMP);
178
+ break;
179
+
180
+ case SQL_TYPE_DATE :
181
+ field->sqldata = (char *)ALLOC(ISC_DATE);
182
+ break;
183
+
184
+ case SQL_TYPE_TIME:
185
+ field->sqldata = (char *)ALLOC(ISC_TIME);
186
+ break;
187
+
188
+ case SQL_VARYING :
189
+ field->sqldata = (char *)ALLOC_N(short, total);
190
+ break;
191
+
192
+ default :
193
+ rb_fireruby_raise(NULL, "Unknown SQL data type encountered.");
194
+ }
195
+ field->sqlind = ALLOC(short);
196
+ *field->sqlind = 0;
197
+ }
198
+ }
199
+
200
+
201
+ /**
202
+ * This method cleans up all the internal memory associated with a XSQLDA.
203
+ *
204
+ * @param da A reference to the XSQLDA to be cleared up.
205
+ *
206
+ */
207
+ void releaseDataArea(XSQLDA *da)
208
+ {
209
+ XSQLVAR *field = da->sqlvar;
210
+ int index;
211
+
212
+ for(index = 0; index < da->sqld; index++, field++)
213
+ {
214
+ int type = (field->sqltype & ~1);
215
+
216
+ switch(type)
217
+ {
218
+ case SQL_ARRAY :
219
+ fprintf(stderr, "Releasing an array (NOT).\n");
220
+ break;
221
+
222
+ case SQL_BLOB :
223
+ free((ISC_QUAD *)field->sqldata);
224
+ break;
225
+
226
+ case SQL_DOUBLE :
227
+ free((double *)field->sqldata);
228
+ break;
229
+
230
+ case SQL_FLOAT :
231
+ free((float *)field->sqldata);
232
+ break;
233
+
234
+ case SQL_INT64 :
235
+ free((int64_t *)field->sqldata);
236
+ break;
237
+
238
+ case SQL_LONG :
239
+ free((int32_t *)field->sqldata);
240
+ break;
241
+
242
+ case SQL_SHORT :
243
+ free((int16_t *)field->sqldata);
244
+ break;
245
+
246
+ case SQL_TEXT :
247
+ free(field->sqldata);
248
+ break;
249
+
250
+ case SQL_TIMESTAMP :
251
+ free((ISC_TIMESTAMP *)field->sqldata);
252
+ break;
253
+
254
+ case SQL_TYPE_DATE :
255
+ free((ISC_DATE *)field->sqldata);
256
+ break;
257
+
258
+ case SQL_TYPE_TIME:
259
+ free((ISC_TIME *)field->sqldata);
260
+ break;
261
+
262
+ case SQL_VARYING :
263
+ free((short *)field->sqldata);
264
+ break;
265
+ }
266
+ if(field->sqlind != NULL)
267
+ {
268
+ free(field->sqlind);
269
+ }
270
+
271
+ field->sqldata = NULL;
272
+ field->sqlind = NULL;
273
+ }
274
+ }
data/ext/DataArea.h ADDED
@@ -0,0 +1,38 @@
1
+ /*------------------------------------------------------------------------------
2
+ * DataArea.h
3
+ *----------------------------------------------------------------------------*/
4
+ /**
5
+ * Copyright � Peter Wood, 2005
6
+ *
7
+ * The contents of this file are subject to the Mozilla Public License Version
8
+ * 1.1 (the "License"); you may not use this file except in compliance with the
9
+ * License. You may obtain a copy of the License at
10
+ *
11
+ * http://www.mozilla.org/MPL/
12
+ *
13
+ * Software distributed under the License is distributed on an "AS IS" basis,
14
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
15
+ * the specificlanguage governing rights and limitations under the License.
16
+ *
17
+ * The Original Code is the FireRuby extension for the Ruby language.
18
+ *
19
+ * The Initial Developer of the Original Code is Peter Wood. All Rights
20
+ * Reserved.
21
+ *
22
+ * @author Peter Wood
23
+ * @version 1.0
24
+ */
25
+ #ifndef FIRERUBY_DATA_AREA_H
26
+ #define FIRERUBY_DATA_AREA_H
27
+
28
+ #ifndef IBASE_H_INCLUDED
29
+ #include "ibase.h"
30
+ #define IBASE_H_INCLUDED
31
+ #endif
32
+
33
+ XSQLDA *allocateOutXSQLDA(int, isc_stmt_handle *, short);
34
+ XSQLDA *allocateInXSQLDA(int, isc_stmt_handle *, short);
35
+ void prepareDataArea(XSQLDA *);
36
+ void releaseDataArea(XSQLDA *);
37
+
38
+ #endif /* FIRERUBY_DATA_AREA_H */
data/ext/Database.c ADDED
@@ -0,0 +1,449 @@
1
+ /*------------------------------------------------------------------------------
2
+ * Database.c
3
+ *----------------------------------------------------------------------------*/
4
+ /**
5
+ * Copyright � Peter Wood, 2005
6
+ *
7
+ * The contents of this file are subject to the Mozilla Public License Version
8
+ * 1.1 (the "License"); you may not use this file except in compliance with the
9
+ * License. You may obtain a copy of the License at
10
+ *
11
+ * http://www.mozilla.org/MPL/
12
+ *
13
+ * Software distributed under the License is distributed on an "AS IS" basis,
14
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
15
+ * the specificlanguage governing rights and limitations under the License.
16
+ *
17
+ * The Original Code is the FireRuby extension for the Ruby language.
18
+ *
19
+ * The Initial Developer of the Original Code is Peter Wood. All Rights
20
+ * Reserved.
21
+ *
22
+ * @author Peter Wood
23
+ * @version 1.0
24
+ */
25
+
26
+ /* Includes. */
27
+ #include "Database.h"
28
+ #include "FireRubyException.h"
29
+ #include "Connection.h"
30
+ #include "ruby.h"
31
+
32
+ /* Function prototypes. */
33
+ static VALUE allocateDatabase(VALUE);
34
+ static VALUE initializeDatabase(int, VALUE *, VALUE);
35
+ static VALUE getDatabaseFile(VALUE);
36
+ static VALUE connectToDatabase(int, VALUE *, VALUE);
37
+ static VALUE createDatabase(int, VALUE *, VALUE);
38
+ static VALUE dropDatabase(VALUE, VALUE, VALUE);
39
+ static VALUE getDatabaseCharacterSet(VALUE);
40
+ static VALUE setDatabaseCharacterSet(VALUE, VALUE);
41
+ VALUE connectBlock(VALUE);
42
+ VALUE connectEnsure(VALUE);
43
+
44
+ /* Globals. */
45
+ VALUE cDatabase;
46
+
47
+
48
+ /**
49
+ * This function provides the functionality to allow for the allocation of
50
+ * new Database objects.
51
+ *
52
+ * @param klass A reference to the Database Class object.
53
+ *
54
+ * @return A reference to the new Database class instance.
55
+ *
56
+ */
57
+ static VALUE allocateDatabase(VALUE klass)
58
+ {
59
+ VALUE instance = Qnil;
60
+ DatabaseHandle *database = ALLOC(DatabaseHandle);
61
+
62
+ if(database != NULL)
63
+ {
64
+ /* Wrap the structure in a class. */
65
+ instance = Data_Wrap_Struct(klass, NULL, databaseFree, database);
66
+ }
67
+ else
68
+ {
69
+ rb_raise(rb_eNoMemError,
70
+ "Memory allocation failure creating a Database object.");
71
+ }
72
+
73
+ return(instance);
74
+ }
75
+
76
+
77
+ /**
78
+ * This function provides the initialize method for the Database class.
79
+ *
80
+ * @param argc A count of the total number of parameters passed to the
81
+ * function.
82
+ * @param argv A pointer to an array containing the parameters passed to the
83
+ * function.
84
+ * @param self A reference to the object that the method call is being made
85
+ * to.
86
+ *
87
+ * @return A reference to the new initialized object instance.
88
+ *
89
+ */
90
+ VALUE initializeDatabase(int argc, VALUE *argv, VALUE self)
91
+ {
92
+ VALUE options = rb_hash_new();
93
+
94
+ /* Check the number of parameters. */
95
+ if(argc < 1)
96
+ {
97
+ rb_raise(rb_eArgError, "Wrong number of arguments (%d for %d).", argc, 1);
98
+ }
99
+
100
+ /* Perform type checks on the input parameters. */
101
+ Check_Type(argv[0], T_STRING);
102
+ if(argc > 1)
103
+ {
104
+ Check_Type(argv[1], T_STRING);
105
+ rb_hash_aset(options, INT2FIX(isc_dpb_lc_ctype), argv[1]);
106
+ }
107
+
108
+ /* Store the database details. */
109
+ rb_iv_set(self, "@file", argv[0]);
110
+ rb_iv_set(self, "@options", options);
111
+
112
+ return(self);
113
+ }
114
+
115
+
116
+ /**
117
+ * This function provides the file attribute accessor for the Database class.
118
+ *
119
+ * @param self A reference to the object that the method is being called on.
120
+ *
121
+ * @return A reference to the database file name associated with the Database
122
+ * object
123
+ *
124
+ */
125
+ static VALUE getDatabaseFile(VALUE self)
126
+ {
127
+ return(rb_iv_get(self, "@file"));
128
+ }
129
+
130
+
131
+ /**
132
+ * This method attempts to open a connection to a database using the details
133
+ * in a Database object.
134
+ *
135
+ * @param argc A count of the number of parameters passed to the function.
136
+ * @param argv A pointer to the start of an array containing the function
137
+ * parameter values.
138
+ * @param self A reference to the object that the call is being made on.
139
+ *
140
+ * @return A reference to a Connection object or nil if an error occurs.
141
+ *
142
+ */
143
+ static VALUE connectToDatabase(int argc, VALUE *argv, VALUE self)
144
+ {
145
+ VALUE result = Qnil,
146
+ user = Qnil,
147
+ password = Qnil,
148
+ options = rb_iv_get(self, "@options"),
149
+ connection = Qnil;
150
+
151
+ if(argc > 0)
152
+ {
153
+ user = argv[0];
154
+ }
155
+ if(argc > 1)
156
+ {
157
+ password = argv[1];
158
+ }
159
+ if(argc > 2)
160
+ {
161
+ rb_funcall(options, rb_intern("update"), 1, argv[2]);
162
+ }
163
+
164
+ connection = rb_connection_new(self, user, password, options);
165
+ if(rb_block_given_p())
166
+ {
167
+ result = rb_ensure(connectBlock, connection, connectEnsure, connection);
168
+ }
169
+ else
170
+ {
171
+ result = connection;
172
+ }
173
+
174
+ return(result);
175
+ }
176
+
177
+
178
+ /**
179
+ * This function provides the create class method for Database class.
180
+ *
181
+ * @param usused Like it says, not used.
182
+ * @param file A String containing the name of the primary file for the
183
+ * database to be created.
184
+ * @param user The database user that will be used in creating the new
185
+ * database.
186
+ * @param password A String containing the password for the user to be used
187
+ * in creating the database.
188
+ * @param size The size of pages that will be used by the database.
189
+ * @param set A String containing the name of the character set to be
190
+ * used in creating the database.
191
+ *
192
+ * @return A reference to a Database object on success, nil on failure.
193
+ *
194
+ */
195
+ static VALUE createDatabase(int argc, VALUE *argv, VALUE unused)
196
+ {
197
+ VALUE database = Qnil,
198
+ set = Qnil;
199
+ char sql[512] = "",
200
+ *text = NULL;
201
+ int value = 1024;
202
+ isc_db_handle connection = 0;
203
+ isc_tr_handle transaction = 0;
204
+ ISC_STATUS status[20];
205
+
206
+ /* Check that sufficient parameters have been provided. */
207
+ if(argc < 3)
208
+ {
209
+ rb_raise(rb_eArgError, "Wrong number of parameters (%d for %d).", argc,
210
+ 3);
211
+ }
212
+
213
+ /* Check values that are permitted restricted values. */
214
+ if(argc > 3)
215
+ {
216
+ value = FIX2INT(argv[3]);
217
+ if(value != 1024 && value != 2048 && value != 4096 && value != 8192)
218
+ {
219
+ rb_raise(rb_eException,
220
+ "Invalid database page size value . Valid values are 1024, "\
221
+ "2048 4096 or 8192.");
222
+ }
223
+ }
224
+
225
+ /* Prepare the SQL statement. */
226
+ sprintf(sql, "CREATE DATABASE '%s'",
227
+ STR2CSTR(rb_funcall(argv[0], rb_intern("to_s"), 0)));
228
+ text = STR2CSTR(rb_funcall(argv[1], rb_intern("to_s"), 0));
229
+ if(strlen(text) > 0)
230
+ {
231
+ strcat(sql, " USER '");
232
+ strcat(sql, text);
233
+ strcat(sql, "'");
234
+ }
235
+
236
+ text = STR2CSTR(rb_funcall(argv[2], rb_intern("to_s"), 0));
237
+ if(strlen(text) > 0)
238
+ {
239
+ strcat(sql, " PASSWORD '");
240
+ strcat(sql, text);
241
+ strcat(sql, "'");
242
+ }
243
+
244
+ if(argc > 3)
245
+ {
246
+ char text[50];
247
+
248
+ sprintf(text, " PAGE_SIZE = %d", value);
249
+ strcat(sql, text);
250
+ }
251
+
252
+ if(argc > 4 && argv[4] != Qnil)
253
+ {
254
+ char *text = NULL;
255
+
256
+ set = rb_funcall(argv[4], rb_intern("to_s"), 0);
257
+ text = STR2CSTR(set);
258
+ if(strlen(text) > 0)
259
+ {
260
+ strcat(sql, " DEFAULT CHARACTER SET ");
261
+ strcat(sql, text);
262
+ }
263
+ }
264
+ strcat(sql, ";");
265
+
266
+ if(isc_dsql_execute_immediate(status, &connection, &transaction, 0, sql,
267
+ 3, NULL) != 0)
268
+ {
269
+ rb_fireruby_raise(status, "Database creation error.");
270
+ }
271
+
272
+ if(connection != 0)
273
+ {
274
+ isc_detach_database(status, &connection);
275
+ }
276
+
277
+ database = rb_database_new(argv[0]);
278
+ if(set != Qnil)
279
+ {
280
+ setDatabaseCharacterSet(database, set);
281
+ }
282
+
283
+ return(database);
284
+ }
285
+
286
+
287
+ /**
288
+ * This function attempts to attach to and drop a specified database. This
289
+ * function provides the drop method for the Database class.
290
+ *
291
+ * @param self A reference to the Database object representing the
292
+ * database to be dropped.
293
+ * @param user A reference to the database user name that will be used
294
+ * in dropping the database
295
+ * @param password A reference to the user password that will be used in
296
+ * dropping the database.
297
+ *
298
+ * @return Always returns nil.
299
+ *
300
+ */
301
+ static VALUE dropDatabase(VALUE self, VALUE user, VALUE password)
302
+ {
303
+ VALUE connection = rb_connection_new(self, user, password, Qnil);
304
+ ConnectionHandle *cHandle = NULL;
305
+ ISC_STATUS status[20];
306
+
307
+ Data_Get_Struct(connection, ConnectionHandle, cHandle);
308
+ if(isc_drop_database(status, &cHandle->handle) != 0)
309
+ {
310
+ rb_fireruby_raise(status, "Error dropping database.");
311
+ }
312
+
313
+ return(Qnil);
314
+ }
315
+
316
+
317
+ /**
318
+ * This function retrieves the current character set specification for a
319
+ * Database object.
320
+ *
321
+ * @param self A reference to the Database object to make the call on.
322
+ *
323
+ * @return A reference to the database character set. May be nil.
324
+ *
325
+ */
326
+ static VALUE getDatabaseCharacterSet(VALUE self)
327
+ {
328
+ VALUE options = rb_iv_get(self, "@options");
329
+
330
+ return(rb_hash_aref(options, INT2FIX(isc_dpb_lc_ctype)));
331
+ }
332
+
333
+
334
+ /**
335
+ * This function assigns a character set for use with a Database object. To
336
+ * revert to an unspecified character set assign nil to this value.
337
+ *
338
+ * @param self A reference to the Database object to be updated.
339
+ * @param set A string containing the name of the character set.
340
+ *
341
+ * @return A reference to the updated Database object.
342
+ *
343
+ */
344
+ static VALUE setDatabaseCharacterSet(VALUE self, VALUE set)
345
+ {
346
+ VALUE options = rb_iv_get(self, "@options");
347
+
348
+ if(set != Qnil)
349
+ {
350
+ rb_hash_aset(options, INT2FIX(isc_dpb_lc_ctype), set);
351
+ }
352
+ else
353
+ {
354
+ rb_hash_delete(options, INT2FIX(isc_dpb_lc_ctype));
355
+ }
356
+
357
+ return(self);
358
+ }
359
+
360
+
361
+ /**
362
+ * This function is used to integrate with the Ruby garbage collection system
363
+ * to guarantee the release of the resources associated with a Database object.
364
+ *
365
+ * @param database A pointer to the DatabaseHandle structure associated with
366
+ * a Database object being destroyed.
367
+ *
368
+ */
369
+ void databaseFree(void *database)
370
+ {
371
+ if(database != NULL)
372
+ {
373
+ free((DatabaseHandle *)database);
374
+ }
375
+ }
376
+
377
+
378
+ /**
379
+ * This function implements the handling of blocks passed to a call to the
380
+ * connect method of the Database class. The block passed to the connect
381
+ * function is expected to take a single parameter, which will be the connection
382
+ * created.
383
+ *
384
+ * @param connection A reference to the connection established for the block.
385
+ *
386
+ * @return The return value provided by execution of the provided block.
387
+ *
388
+ */
389
+ VALUE connectBlock(VALUE connection)
390
+ {
391
+ return(rb_yield(connection));
392
+ }
393
+
394
+
395
+ /**
396
+ * This function provides the ensure aspect for the block handling associated
397
+ * with the connect method. This method ensures that the connection opened for
398
+ * the block is closed when the block completes.
399
+ *
400
+ * @param connection A reference to the connection to be closed.
401
+ *
402
+ * @return Always Qnil.
403
+ *
404
+ */
405
+ VALUE connectEnsure(VALUE connection)
406
+ {
407
+ rb_funcall(connection, rb_intern("close"), 0);
408
+ return(Qnil);
409
+ }
410
+
411
+
412
+ /**
413
+ * This function provides a means to programmatically create a Database object.
414
+ *
415
+ * @param file A reference to a String containing the database file details.
416
+ *
417
+ * @return A reference to the Database object created.
418
+ *
419
+ */
420
+ VALUE rb_database_new(VALUE file)
421
+ {
422
+ VALUE database = allocateDatabase(cDatabase),
423
+ parameters[] = {file};
424
+
425
+ initializeDatabase(1, parameters, database);
426
+
427
+ return(database);
428
+ }
429
+
430
+
431
+ /**
432
+ * This function initializes the Database class within the Ruby environment.
433
+ * The class is established under the module specified to the function.
434
+ *
435
+ * @param module A reference to the module to create the class within.
436
+ *
437
+ */
438
+ void Init_Database(VALUE module)
439
+ {
440
+ cDatabase = rb_define_class_under(module, "Database", rb_cObject);
441
+ rb_define_alloc_func(cDatabase, allocateDatabase);
442
+ rb_define_method(cDatabase, "initialize", initializeDatabase, -1);
443
+ rb_define_method(cDatabase, "file", getDatabaseFile, 0);
444
+ rb_define_method(cDatabase, "connect", connectToDatabase, -1);
445
+ rb_define_method(cDatabase, "drop", dropDatabase, 2);
446
+ rb_define_method(cDatabase, "character_set", getDatabaseCharacterSet, 0);
447
+ rb_define_method(cDatabase, "character_set=", setDatabaseCharacterSet, 1);
448
+ rb_define_module_function(cDatabase, "create", createDatabase, -1);
449
+ }