libsql 0.1.0-x64-mingw-ucrt
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.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +60 -0
- data/HISTORY.md +6 -0
- data/LICENSE +31 -0
- data/Manifest.txt +96 -0
- data/README.md +59 -0
- data/Rakefile +28 -0
- data/TODO.md +57 -0
- data/examples/a.rb +9 -0
- data/examples/blob.rb +106 -0
- data/examples/define_aggregate.rb +75 -0
- data/examples/define_function.rb +104 -0
- data/examples/fts5.rb +152 -0
- data/examples/gem-db.rb +94 -0
- data/examples/schema-info.rb +34 -0
- data/ext/libsql/c/extconf.rb +86 -0
- data/ext/libsql/c/gen_constants.rb +353 -0
- data/ext/libsql/c/libsql_blob.c +240 -0
- data/ext/libsql/c/libsql_constants.c +1518 -0
- data/ext/libsql/c/libsql_database.c +1188 -0
- data/ext/libsql/c/libsql_ext.c +383 -0
- data/ext/libsql/c/libsql_ext.h +149 -0
- data/ext/libsql/c/libsql_statement.c +649 -0
- data/ext/libsql/c/notes.txt +134 -0
- data/ext/libsql/c/sqlite3.c +247030 -0
- data/ext/libsql/c/sqlite3.h +13436 -0
- data/lib/libsql/3.1/libsql_ext.so +0 -0
- data/lib/libsql/3.2/libsql_ext.so +0 -0
- data/lib/libsql/aggregate.rb +73 -0
- data/lib/libsql/blob.rb +186 -0
- data/lib/libsql/boolean.rb +42 -0
- data/lib/libsql/busy_timeout.rb +47 -0
- data/lib/libsql/column.rb +99 -0
- data/lib/libsql/csv_table_importer.rb +75 -0
- data/lib/libsql/database.rb +933 -0
- data/lib/libsql/function.rb +61 -0
- data/lib/libsql/index.rb +43 -0
- data/lib/libsql/memory_database.rb +15 -0
- data/lib/libsql/paths.rb +80 -0
- data/lib/libsql/profile_tap.rb +131 -0
- data/lib/libsql/progress_handler.rb +21 -0
- data/lib/libsql/schema.rb +225 -0
- data/lib/libsql/sqlite3/constants.rb +95 -0
- data/lib/libsql/sqlite3/database/function.rb +48 -0
- data/lib/libsql/sqlite3/database/status.rb +68 -0
- data/lib/libsql/sqlite3/libsql_version.rb +32 -0
- data/lib/libsql/sqlite3/status.rb +60 -0
- data/lib/libsql/sqlite3/version.rb +55 -0
- data/lib/libsql/sqlite3.rb +7 -0
- data/lib/libsql/statement.rb +421 -0
- data/lib/libsql/table.rb +91 -0
- data/lib/libsql/taps/console.rb +27 -0
- data/lib/libsql/taps/io.rb +74 -0
- data/lib/libsql/taps.rb +2 -0
- data/lib/libsql/trace_tap.rb +35 -0
- data/lib/libsql/type_map.rb +63 -0
- data/lib/libsql/type_maps/default_map.rb +166 -0
- data/lib/libsql/type_maps/storage_map.rb +38 -0
- data/lib/libsql/type_maps/text_map.rb +21 -0
- data/lib/libsql/version.rb +8 -0
- data/lib/libsql/view.rb +26 -0
- data/lib/libsql-ruby.rb +1 -0
- data/lib/libsql.rb +51 -0
- data/spec/aggregate_spec.rb +158 -0
- data/spec/blob_spec.rb +78 -0
- data/spec/boolean_spec.rb +24 -0
- data/spec/busy_handler.rb +157 -0
- data/spec/data/iso-3166-country.txt +242 -0
- data/spec/data/iso-3166-schema.sql +22 -0
- data/spec/data/iso-3166-subcountry.txt +3995 -0
- data/spec/data/make-iso-db.sh +12 -0
- data/spec/database_spec.rb +505 -0
- data/spec/default_map_spec.rb +92 -0
- data/spec/function_spec.rb +78 -0
- data/spec/integeration_spec.rb +97 -0
- data/spec/iso_3166_database.rb +58 -0
- data/spec/json_spec.rb +24 -0
- data/spec/libsql_spec.rb +4 -0
- data/spec/paths_spec.rb +28 -0
- data/spec/progress_handler_spec.rb +91 -0
- data/spec/rtree_spec.rb +66 -0
- data/spec/schema_spec.rb +131 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/sqlite3/constants_spec.rb +108 -0
- data/spec/sqlite3/database_status_spec.rb +36 -0
- data/spec/sqlite3/libsql_version_spec.rb +16 -0
- data/spec/sqlite3/status_spec.rb +22 -0
- data/spec/sqlite3/version_spec.rb +28 -0
- data/spec/sqlite3_spec.rb +53 -0
- data/spec/statement_spec.rb +168 -0
- data/spec/storage_map_spec.rb +38 -0
- data/spec/tap_spec.rb +57 -0
- data/spec/text_map_spec.rb +20 -0
- data/spec/type_map_spec.rb +14 -0
- data/spec/version_spec.rb +8 -0
- data/tasks/custom.rake +134 -0
- data/tasks/default.rake +257 -0
- data/tasks/extension.rake +29 -0
- data/tasks/this.rb +208 -0
- metadata +329 -0
@@ -0,0 +1,649 @@
|
|
1
|
+
#include "libsql_ext.h"
|
2
|
+
/**
|
3
|
+
* Copyright (c) 2023 Jeremy Hinegardner
|
4
|
+
* All rights reserved. See LICENSE and/or COPYING for details.
|
5
|
+
*
|
6
|
+
* vim: shiftwidth=4
|
7
|
+
*/
|
8
|
+
|
9
|
+
VALUE cLS_Statement; /* class Amalgliate::SQLite3::Statement */
|
10
|
+
|
11
|
+
/**
|
12
|
+
* call-seq:
|
13
|
+
* stmt.bind_null( position ) -> int
|
14
|
+
*
|
15
|
+
* bind a null value to the variable at postion.
|
16
|
+
*
|
17
|
+
*/
|
18
|
+
VALUE libsql_ext_sqlite3_statement_bind_null(VALUE self, VALUE position )
|
19
|
+
{
|
20
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
21
|
+
int pos = FIX2INT( position );
|
22
|
+
int rc;
|
23
|
+
|
24
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
25
|
+
rc = sqlite3_bind_null( libsql_ext_stmt->stmt, pos );
|
26
|
+
if ( SQLITE_OK != rc ) {
|
27
|
+
rb_raise(eLS_Error, "Error binding NULL at position %d in statement: [SQLITE_ERROR %d] : %s\n",
|
28
|
+
pos,
|
29
|
+
rc, sqlite3_errmsg( sqlite3_db_handle( libsql_ext_stmt->stmt) ));
|
30
|
+
}
|
31
|
+
|
32
|
+
return INT2FIX(rc);
|
33
|
+
}
|
34
|
+
|
35
|
+
/**
|
36
|
+
* call-seq:
|
37
|
+
* stmt.bind_zeroblob( position, length ) -> int
|
38
|
+
*
|
39
|
+
* bind a blob with +length+ filled with zeros to the position. This is a Blob
|
40
|
+
* that will later filled in with incremental IO routines.
|
41
|
+
*/
|
42
|
+
VALUE libsql_ext_sqlite3_statement_bind_zeroblob( VALUE self, VALUE position, VALUE length)
|
43
|
+
{
|
44
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
45
|
+
int pos = FIX2INT( position );
|
46
|
+
int n = (int)FIX2INT( length );
|
47
|
+
int rc;
|
48
|
+
|
49
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
50
|
+
rc = sqlite3_bind_zeroblob( libsql_ext_stmt->stmt, pos, n );
|
51
|
+
if ( SQLITE_OK != rc ) {
|
52
|
+
rb_raise(eLS_Error, "Error binding zeroblob of length %d at position %d in statement: [SQLITE_ERROR %d] : %s\n",
|
53
|
+
n, pos,
|
54
|
+
rc, sqlite3_errmsg( sqlite3_db_handle( libsql_ext_stmt->stmt) ));
|
55
|
+
}
|
56
|
+
|
57
|
+
return INT2FIX(rc);
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
/**
|
62
|
+
* call-seq:
|
63
|
+
* stmt.bind_blob( position, blob ) -> int
|
64
|
+
*
|
65
|
+
* bind a blob to the variable at position. This is a blob that is fully held
|
66
|
+
* in memory
|
67
|
+
*/
|
68
|
+
VALUE libsql_ext_sqlite3_statement_bind_blob( VALUE self, VALUE position, VALUE blob )
|
69
|
+
{
|
70
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
71
|
+
int pos = FIX2INT( position );
|
72
|
+
VALUE str = StringValue( blob );
|
73
|
+
int rc;
|
74
|
+
|
75
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
76
|
+
rc = sqlite3_bind_blob( libsql_ext_stmt->stmt, pos, RSTRING_PTR( str ), (int)RSTRING_LEN( str ), SQLITE_TRANSIENT);
|
77
|
+
if ( SQLITE_OK != rc ) {
|
78
|
+
rb_raise(eLS_Error, "Error binding blob at position %d in statement: [SQLITE_ERROR %d] : %s\n",
|
79
|
+
pos,
|
80
|
+
rc, sqlite3_errmsg( sqlite3_db_handle( libsql_ext_stmt->stmt) ));
|
81
|
+
}
|
82
|
+
|
83
|
+
return INT2FIX(rc);
|
84
|
+
}
|
85
|
+
|
86
|
+
/**
|
87
|
+
* call-seq:
|
88
|
+
* stmt.bind_double( position, value ) -> nil
|
89
|
+
*
|
90
|
+
* bind a double value to the variable at postion.
|
91
|
+
*
|
92
|
+
*/
|
93
|
+
VALUE libsql_ext_sqlite3_statement_bind_double(VALUE self, VALUE position, VALUE value)
|
94
|
+
{
|
95
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
96
|
+
int pos = FIX2INT( position );
|
97
|
+
double v = NUM2DBL( value );
|
98
|
+
int rc;
|
99
|
+
|
100
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
101
|
+
rc = sqlite3_bind_double( libsql_ext_stmt->stmt, pos, v );
|
102
|
+
if ( SQLITE_OK != rc ) {
|
103
|
+
rb_raise(eLS_Error, "Error binding [%lf] to double at position %d in statement: [SQLITE_ERROR %d] : %s\n",
|
104
|
+
v, pos,
|
105
|
+
rc, (char*)sqlite3_errmsg( sqlite3_db_handle( libsql_ext_stmt->stmt) ));
|
106
|
+
}
|
107
|
+
|
108
|
+
return INT2FIX(rc);
|
109
|
+
}
|
110
|
+
|
111
|
+
/**
|
112
|
+
* call-seq:
|
113
|
+
* stmt.bind_int( position, value ) -> nil
|
114
|
+
*
|
115
|
+
* bind a int value to the variable at postion.
|
116
|
+
*
|
117
|
+
*/
|
118
|
+
VALUE libsql_ext_sqlite3_statement_bind_int(VALUE self, VALUE position, VALUE value)
|
119
|
+
{
|
120
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
121
|
+
int pos = FIX2INT( position );
|
122
|
+
int v = NUM2INT( value );
|
123
|
+
int rc;
|
124
|
+
|
125
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
126
|
+
rc = sqlite3_bind_int( libsql_ext_stmt->stmt, pos, v );
|
127
|
+
if ( SQLITE_OK != rc ) {
|
128
|
+
rb_raise(eLS_Error, "Error binding [%d] to int at position %d in statement: [SQLITE_ERROR %d] : %s\n",
|
129
|
+
v, pos,
|
130
|
+
rc, sqlite3_errmsg( sqlite3_db_handle( libsql_ext_stmt->stmt) ));
|
131
|
+
}
|
132
|
+
|
133
|
+
return INT2FIX(rc);
|
134
|
+
}
|
135
|
+
|
136
|
+
/**
|
137
|
+
* call-seq:
|
138
|
+
* stmt.bind_int64( position, value ) -> nil
|
139
|
+
*
|
140
|
+
* bind a int64 value to the variable at postion.
|
141
|
+
*
|
142
|
+
*/
|
143
|
+
VALUE libsql_ext_sqlite3_statement_bind_int64(VALUE self, VALUE position, VALUE value)
|
144
|
+
{
|
145
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
146
|
+
int pos = FIX2INT( position );
|
147
|
+
sqlite3_int64 v = NUM2SQLINT64( value );
|
148
|
+
int rc;
|
149
|
+
|
150
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
151
|
+
rc = sqlite3_bind_int64( libsql_ext_stmt->stmt, pos, v );
|
152
|
+
if ( SQLITE_OK != rc ) {
|
153
|
+
rb_raise(eLS_Error, "Error binding [%lld] to int64 at position %d in statement: [SQLITE_ERROR %d] : %s\n",
|
154
|
+
v, pos,
|
155
|
+
rc, sqlite3_errmsg( sqlite3_db_handle( libsql_ext_stmt->stmt) ));
|
156
|
+
}
|
157
|
+
|
158
|
+
return INT2FIX(rc);
|
159
|
+
}
|
160
|
+
|
161
|
+
/**
|
162
|
+
* call-seq:
|
163
|
+
* stmt.bind_text( position, value ) -> nil
|
164
|
+
*
|
165
|
+
* bind a string value to the variable at postion.
|
166
|
+
*
|
167
|
+
*/
|
168
|
+
VALUE libsql_ext_sqlite3_statement_bind_text(VALUE self, VALUE position, VALUE value)
|
169
|
+
{
|
170
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
171
|
+
int pos = FIX2INT( position );
|
172
|
+
VALUE str = StringValue( value );
|
173
|
+
int rc;
|
174
|
+
|
175
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
176
|
+
rc = sqlite3_bind_text( libsql_ext_stmt->stmt, pos, RSTRING_PTR(str), (int)RSTRING_LEN(str), SQLITE_TRANSIENT);
|
177
|
+
if ( SQLITE_OK != rc ) {
|
178
|
+
rb_raise(eLS_Error, "Error binding [%s] to text at position %d in statement: [SQLITE_ERROR %d] : %s\n",
|
179
|
+
RSTRING_PTR(str), pos,
|
180
|
+
rc, sqlite3_errmsg( sqlite3_db_handle( libsql_ext_stmt->stmt) ));
|
181
|
+
}
|
182
|
+
|
183
|
+
return INT2FIX(rc);
|
184
|
+
}
|
185
|
+
/**
|
186
|
+
* call-seq:
|
187
|
+
* stmt.remaining_sql -> String
|
188
|
+
*
|
189
|
+
* returns the remainging SQL leftover from the initialization sql, or nil if
|
190
|
+
* there is no remaining SQL
|
191
|
+
*/
|
192
|
+
VALUE libsql_ext_sqlite3_statement_remaining_sql(VALUE self)
|
193
|
+
{
|
194
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
195
|
+
|
196
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
197
|
+
return libsql_ext_stmt->remaining_sql;
|
198
|
+
}
|
199
|
+
/**
|
200
|
+
* call-seq:
|
201
|
+
* stmt.parameter_index( name ) -> Integer
|
202
|
+
*
|
203
|
+
* returns the index of the named parameter from the statement. Used to help
|
204
|
+
* with the :VVV, @VVV and $VVV pareamter replacement styles.
|
205
|
+
*/
|
206
|
+
VALUE libsql_ext_sqlite3_statement_bind_parameter_index(VALUE self, VALUE parameter_name)
|
207
|
+
{
|
208
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
209
|
+
int idx;
|
210
|
+
|
211
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
212
|
+
idx = sqlite3_bind_parameter_index( libsql_ext_stmt->stmt, StringValuePtr( parameter_name ));
|
213
|
+
return INT2FIX( idx );
|
214
|
+
}
|
215
|
+
|
216
|
+
/**
|
217
|
+
* call-seq:
|
218
|
+
* stmt.parameter_count -> Integer
|
219
|
+
*
|
220
|
+
* return the index of the largest parameter in the in the statement. For all
|
221
|
+
* forms except ?NNN this is the number of unique parameters. Using ?NNN can
|
222
|
+
* create gaps in the list of parameters.
|
223
|
+
*
|
224
|
+
*/
|
225
|
+
VALUE libsql_ext_sqlite3_statement_bind_parameter_count(VALUE self)
|
226
|
+
{
|
227
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
228
|
+
|
229
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
230
|
+
return INT2FIX(sqlite3_bind_parameter_count( libsql_ext_stmt->stmt ) );
|
231
|
+
}
|
232
|
+
|
233
|
+
/**
|
234
|
+
* call-seq:
|
235
|
+
* stmt.reset! -> nil
|
236
|
+
*
|
237
|
+
* reset the SQLite3 statement back to its initial state.
|
238
|
+
*/
|
239
|
+
VALUE libsql_ext_sqlite3_statement_reset(VALUE self)
|
240
|
+
{
|
241
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
242
|
+
int rc;
|
243
|
+
|
244
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
245
|
+
if ( libsql_ext_stmt->stmt ) {
|
246
|
+
rc = sqlite3_reset( libsql_ext_stmt->stmt );
|
247
|
+
if ( rc != SQLITE_OK ) {
|
248
|
+
rb_raise(eLS_Error, "Error resetting statement: [SQLITE_ERROR %d] : %s\n",
|
249
|
+
rc, sqlite3_errmsg( sqlite3_db_handle( libsql_ext_stmt->stmt) ));
|
250
|
+
}
|
251
|
+
return Qnil;
|
252
|
+
} else {
|
253
|
+
rb_raise(eLS_Error, "Attempting to free a non-existent statement");
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
/**
|
258
|
+
* call-seq:
|
259
|
+
* stmt.clear_bindings! -> nil
|
260
|
+
*
|
261
|
+
* reset the SQLite3 statement back to its initial state.
|
262
|
+
*/
|
263
|
+
VALUE libsql_ext_sqlite3_statement_clear_bindings(VALUE self)
|
264
|
+
{
|
265
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
266
|
+
int rc;
|
267
|
+
|
268
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
269
|
+
rc = sqlite3_clear_bindings( libsql_ext_stmt->stmt );
|
270
|
+
if ( rc != SQLITE_OK ) {
|
271
|
+
rb_raise(eLS_Error, "Error resetting statement: [SQLITE_ERROR %d] : %s\n",
|
272
|
+
rc, sqlite3_errmsg( sqlite3_db_handle( libsql_ext_stmt->stmt) ));
|
273
|
+
}
|
274
|
+
return Qnil;
|
275
|
+
}
|
276
|
+
|
277
|
+
|
278
|
+
/**
|
279
|
+
* call-seq:
|
280
|
+
* stmt.step -> int
|
281
|
+
*
|
282
|
+
* Step through the next piece of the SQLite3 statement
|
283
|
+
*
|
284
|
+
*/
|
285
|
+
VALUE libsql_ext_sqlite3_statement_step(VALUE self)
|
286
|
+
{
|
287
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
288
|
+
|
289
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
290
|
+
return INT2FIX( sqlite3_step( libsql_ext_stmt->stmt ) );
|
291
|
+
}
|
292
|
+
|
293
|
+
/**
|
294
|
+
* call-seq:
|
295
|
+
* stmt.column_count -> Fixnum
|
296
|
+
*
|
297
|
+
* return the number of columns in the result set.
|
298
|
+
*
|
299
|
+
*/
|
300
|
+
VALUE libsql_ext_sqlite3_statement_column_count(VALUE self)
|
301
|
+
{
|
302
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
303
|
+
|
304
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
305
|
+
return INT2FIX( sqlite3_column_count( libsql_ext_stmt->stmt ) );
|
306
|
+
}
|
307
|
+
|
308
|
+
/**
|
309
|
+
* call-seq:
|
310
|
+
* stmt.column_name( index ) -> String
|
311
|
+
*
|
312
|
+
* Return the column name at the ith column in the result set. The left-most column
|
313
|
+
* is number 0.
|
314
|
+
*
|
315
|
+
*/
|
316
|
+
VALUE libsql_ext_sqlite3_statement_column_name(VALUE self, VALUE v_idx)
|
317
|
+
{
|
318
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
319
|
+
int idx = FIX2INT( v_idx );
|
320
|
+
|
321
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
322
|
+
|
323
|
+
return rb_str_new2( sqlite3_column_name( libsql_ext_stmt->stmt, idx ) );
|
324
|
+
}
|
325
|
+
|
326
|
+
|
327
|
+
/**
|
328
|
+
* call-seq:
|
329
|
+
* stmt.column_declared_type( index ) -> String
|
330
|
+
*
|
331
|
+
* Return the declared type of the ith column in the result set. This is the
|
332
|
+
* value that was in the original CREATE TABLE statement.
|
333
|
+
*
|
334
|
+
*/
|
335
|
+
VALUE libsql_ext_sqlite3_statement_column_decltype(VALUE self, VALUE v_idx)
|
336
|
+
{
|
337
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
338
|
+
int idx = FIX2INT( v_idx );
|
339
|
+
const char *decltype;
|
340
|
+
|
341
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
342
|
+
decltype = sqlite3_column_decltype( libsql_ext_stmt->stmt, idx ) ;
|
343
|
+
if ( NULL == decltype) {
|
344
|
+
return Qnil;
|
345
|
+
} else {
|
346
|
+
return rb_str_new2( decltype );
|
347
|
+
}
|
348
|
+
}
|
349
|
+
|
350
|
+
/**
|
351
|
+
* call-seq:
|
352
|
+
* stmt.column_type( index ) -> SQLite3::DataType constant
|
353
|
+
*
|
354
|
+
* Return the column type at the ith column in the result set. The left-most column
|
355
|
+
* is number 0.
|
356
|
+
*
|
357
|
+
*/
|
358
|
+
VALUE libsql_ext_sqlite3_statement_column_type(VALUE self, VALUE v_idx)
|
359
|
+
{
|
360
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
361
|
+
int idx = FIX2INT( v_idx );
|
362
|
+
|
363
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
364
|
+
return INT2FIX( sqlite3_column_type( libsql_ext_stmt->stmt, idx ) );
|
365
|
+
}
|
366
|
+
|
367
|
+
/**
|
368
|
+
* call-seq:
|
369
|
+
* stmt.column_text( index ) -> String
|
370
|
+
*
|
371
|
+
* Return the data in ith column of the result as a String.
|
372
|
+
*
|
373
|
+
*/
|
374
|
+
VALUE libsql_ext_sqlite3_statement_column_text(VALUE self, VALUE v_idx)
|
375
|
+
{
|
376
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
377
|
+
int idx = FIX2INT( v_idx );
|
378
|
+
|
379
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
380
|
+
return rb_str_new2( (const char*)sqlite3_column_text( libsql_ext_stmt->stmt, idx ) );
|
381
|
+
}
|
382
|
+
|
383
|
+
/**
|
384
|
+
* call-seq:
|
385
|
+
* stmt.column_blob( index ) -> String
|
386
|
+
*
|
387
|
+
* Return the data in ith column of the result as a String.
|
388
|
+
*
|
389
|
+
*/
|
390
|
+
VALUE libsql_ext_sqlite3_statement_column_blob(VALUE self, VALUE v_idx)
|
391
|
+
{
|
392
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
393
|
+
int idx = FIX2INT( v_idx );
|
394
|
+
const char *data;
|
395
|
+
long length;
|
396
|
+
|
397
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
398
|
+
data = sqlite3_column_blob( libsql_ext_stmt->stmt, idx );
|
399
|
+
length = sqlite3_column_bytes( libsql_ext_stmt->stmt, idx );
|
400
|
+
return rb_str_new( data, length );
|
401
|
+
|
402
|
+
}
|
403
|
+
|
404
|
+
|
405
|
+
/**
|
406
|
+
* call-seq:
|
407
|
+
* stmt.column_double( index ) -> Float
|
408
|
+
*
|
409
|
+
* Return the data in ith column of the result as an Float
|
410
|
+
*
|
411
|
+
*/
|
412
|
+
VALUE libsql_ext_sqlite3_statement_column_double(VALUE self, VALUE v_idx)
|
413
|
+
{
|
414
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
415
|
+
int idx = FIX2INT( v_idx );
|
416
|
+
|
417
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
418
|
+
return rb_float_new( sqlite3_column_double( libsql_ext_stmt->stmt, idx )) ;
|
419
|
+
}
|
420
|
+
|
421
|
+
|
422
|
+
/**
|
423
|
+
* call-seq:
|
424
|
+
* stmt.column_int( index ) -> Integer
|
425
|
+
*
|
426
|
+
* Return the data in ith column of the result as an Integer
|
427
|
+
*
|
428
|
+
*/
|
429
|
+
VALUE libsql_ext_sqlite3_statement_column_int(VALUE self, VALUE v_idx)
|
430
|
+
{
|
431
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
432
|
+
int idx = FIX2INT( v_idx );
|
433
|
+
|
434
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
435
|
+
return INT2NUM( sqlite3_column_int( libsql_ext_stmt->stmt, idx )) ;
|
436
|
+
}
|
437
|
+
|
438
|
+
|
439
|
+
/**
|
440
|
+
* call-seq:
|
441
|
+
* stmt.column_int64( index ) -> Integer
|
442
|
+
*
|
443
|
+
* Return the data in ith column of the result as an Integer
|
444
|
+
*
|
445
|
+
*/
|
446
|
+
VALUE libsql_ext_sqlite3_statement_column_int64(VALUE self, VALUE v_idx)
|
447
|
+
{
|
448
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
449
|
+
int idx = FIX2INT( v_idx );
|
450
|
+
|
451
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
452
|
+
return SQLINT64_2NUM( sqlite3_column_int64( libsql_ext_stmt->stmt, idx )) ;
|
453
|
+
}
|
454
|
+
|
455
|
+
|
456
|
+
|
457
|
+
/**
|
458
|
+
* call-seq:
|
459
|
+
* stmt.column_database_name( index ) -> String
|
460
|
+
*
|
461
|
+
* Return the database name where the data in the ith column of the result set
|
462
|
+
* comes from.
|
463
|
+
*
|
464
|
+
*/
|
465
|
+
VALUE libsql_ext_sqlite3_statement_column_database_name(VALUE self, VALUE v_idx)
|
466
|
+
{
|
467
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
468
|
+
int idx = FIX2INT( v_idx );
|
469
|
+
const char *n ;
|
470
|
+
|
471
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
472
|
+
n = sqlite3_column_database_name( libsql_ext_stmt->stmt, idx ) ;
|
473
|
+
return ( n == NULL ? Qnil : rb_str_new2( n ) );
|
474
|
+
}
|
475
|
+
|
476
|
+
/**
|
477
|
+
* call-seq:
|
478
|
+
* stmt.column_table_name( index ) -> String
|
479
|
+
*
|
480
|
+
* Return the table name where the data in the ith column of the result set
|
481
|
+
* comes from.
|
482
|
+
*
|
483
|
+
*/
|
484
|
+
VALUE libsql_ext_sqlite3_statement_column_table_name(VALUE self, VALUE v_idx)
|
485
|
+
{
|
486
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
487
|
+
int idx = FIX2INT( v_idx );
|
488
|
+
const char *n ;
|
489
|
+
|
490
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
491
|
+
n = sqlite3_column_table_name( libsql_ext_stmt->stmt, idx );
|
492
|
+
return ( n == NULL ? Qnil : rb_str_new2( n ) );
|
493
|
+
}
|
494
|
+
|
495
|
+
|
496
|
+
/**
|
497
|
+
* call-seq:
|
498
|
+
* stmt.column_origin_name( index ) -> String
|
499
|
+
*
|
500
|
+
* Return the column name where the data in the ith column of the result set
|
501
|
+
* comes from.
|
502
|
+
*
|
503
|
+
*/
|
504
|
+
VALUE libsql_ext_sqlite3_statement_column_origin_name(VALUE self, VALUE v_idx)
|
505
|
+
{
|
506
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
507
|
+
int idx = FIX2INT( v_idx );
|
508
|
+
const char *n ;
|
509
|
+
|
510
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
511
|
+
n = sqlite3_column_origin_name( libsql_ext_stmt->stmt, idx );
|
512
|
+
return ( n == NULL ? Qnil : rb_str_new2( n ) );
|
513
|
+
}
|
514
|
+
|
515
|
+
|
516
|
+
/**
|
517
|
+
* call-seq:
|
518
|
+
* stmt.sql -> String
|
519
|
+
*
|
520
|
+
* Return a copy of the original string used to create the prepared statement.
|
521
|
+
*/
|
522
|
+
VALUE libsql_ext_sqlite3_statement_sql(VALUE self)
|
523
|
+
{
|
524
|
+
|
525
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
526
|
+
|
527
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
528
|
+
return rb_str_new2( sqlite3_sql( libsql_ext_stmt->stmt ) );
|
529
|
+
|
530
|
+
}
|
531
|
+
|
532
|
+
/**
|
533
|
+
* call-seq:
|
534
|
+
* stmt.close -> nil
|
535
|
+
*
|
536
|
+
* Closes the statement. If there is a problem closing the statement then an
|
537
|
+
* error is raised. Closing a statement when there is an existing error is
|
538
|
+
* perfectly fine.
|
539
|
+
*
|
540
|
+
*/
|
541
|
+
VALUE libsql_ext_sqlite3_statement_close( VALUE self )
|
542
|
+
{
|
543
|
+
|
544
|
+
libsql_ext_sqlite3_stmt *libsql_ext_stmt;
|
545
|
+
int rc, existing_errcode;
|
546
|
+
|
547
|
+
Data_Get_Struct(self, libsql_ext_sqlite3_stmt, libsql_ext_stmt);
|
548
|
+
|
549
|
+
/* check the current error code to see if one exists, we could be
|
550
|
+
* closing a statement that has an error, and in that case we do not want to
|
551
|
+
* raise an additional error, we want to let the existing error stand
|
552
|
+
*/
|
553
|
+
existing_errcode = sqlite3_errcode( sqlite3_db_handle( libsql_ext_stmt->stmt ) );
|
554
|
+
rc = sqlite3_finalize( libsql_ext_stmt->stmt );
|
555
|
+
|
556
|
+
if ( (SQLITE_OK != rc) && (rc != existing_errcode) ) {
|
557
|
+
rb_raise(eLS_Error, "Failure to close statement : [SQLITE_ERROR %d] : %s\n",
|
558
|
+
rc, sqlite3_errmsg( sqlite3_db_handle( libsql_ext_stmt->stmt) ));
|
559
|
+
}
|
560
|
+
libsql_ext_stmt->stmt = NULL;
|
561
|
+
|
562
|
+
return Qnil;
|
563
|
+
}
|
564
|
+
|
565
|
+
/***********************************************************************
|
566
|
+
* Ruby life cycle methods
|
567
|
+
***********************************************************************/
|
568
|
+
|
569
|
+
|
570
|
+
/*
|
571
|
+
* garbage collector free method for the libsql_ext_sqlite3_statement structure
|
572
|
+
*/
|
573
|
+
void libsql_ext_sqlite3_statement_free(libsql_ext_sqlite3_stmt* wrapper)
|
574
|
+
{
|
575
|
+
|
576
|
+
if ( Qnil != wrapper->remaining_sql ) {
|
577
|
+
rb_gc_unregister_address( &(wrapper->remaining_sql) );
|
578
|
+
wrapper->remaining_sql = Qnil;
|
579
|
+
}
|
580
|
+
if ( NULL != wrapper->stmt ) {
|
581
|
+
sqlite3_finalize( wrapper->stmt );
|
582
|
+
wrapper->stmt = NULL;
|
583
|
+
}
|
584
|
+
free(wrapper);
|
585
|
+
return;
|
586
|
+
}
|
587
|
+
|
588
|
+
/*
|
589
|
+
* allocate the libsql_ext_data structure
|
590
|
+
*/
|
591
|
+
VALUE libsql_ext_sqlite3_statement_alloc(VALUE klass)
|
592
|
+
{
|
593
|
+
libsql_ext_sqlite3_stmt *wrapper = ALLOC(libsql_ext_sqlite3_stmt);
|
594
|
+
VALUE obj = (VALUE)NULL;
|
595
|
+
|
596
|
+
wrapper->remaining_sql = Qnil;
|
597
|
+
wrapper->stmt = NULL;
|
598
|
+
|
599
|
+
obj = Data_Wrap_Struct(klass, NULL, libsql_ext_sqlite3_statement_free, wrapper);
|
600
|
+
return obj;
|
601
|
+
}
|
602
|
+
|
603
|
+
/**
|
604
|
+
* Amagalite Database extension
|
605
|
+
*/
|
606
|
+
|
607
|
+
void Init_libsql_ext_statement( )
|
608
|
+
{
|
609
|
+
|
610
|
+
VALUE ma = rb_define_module("Libsql");
|
611
|
+
VALUE mas = rb_define_module_under(ma, "SQLite3");
|
612
|
+
|
613
|
+
/*
|
614
|
+
* Encapsulate the SQLite3 Statement handle in a class
|
615
|
+
*/
|
616
|
+
cLS_Statement = rb_define_class_under( mas, "Statement", rb_cObject );
|
617
|
+
rb_define_alloc_func(cLS_Statement, libsql_ext_sqlite3_statement_alloc);
|
618
|
+
rb_define_method(cLS_Statement, "sql", libsql_ext_sqlite3_statement_sql, 0);
|
619
|
+
rb_define_method(cLS_Statement, "close", libsql_ext_sqlite3_statement_close, 0);
|
620
|
+
rb_define_method(cLS_Statement, "step", libsql_ext_sqlite3_statement_step, 0);
|
621
|
+
|
622
|
+
rb_define_method(cLS_Statement, "column_count", libsql_ext_sqlite3_statement_column_count, 0);
|
623
|
+
rb_define_method(cLS_Statement, "column_name", libsql_ext_sqlite3_statement_column_name, 1);
|
624
|
+
rb_define_method(cLS_Statement, "column_declared_type", libsql_ext_sqlite3_statement_column_decltype, 1);
|
625
|
+
rb_define_method(cLS_Statement, "column_type", libsql_ext_sqlite3_statement_column_type, 1);
|
626
|
+
rb_define_method(cLS_Statement, "column_text", libsql_ext_sqlite3_statement_column_text, 1);
|
627
|
+
rb_define_method(cLS_Statement, "column_blob", libsql_ext_sqlite3_statement_column_blob, 1);
|
628
|
+
rb_define_method(cLS_Statement, "column_int", libsql_ext_sqlite3_statement_column_int, 1);
|
629
|
+
rb_define_method(cLS_Statement, "column_int64", libsql_ext_sqlite3_statement_column_int64, 1);
|
630
|
+
rb_define_method(cLS_Statement, "column_double", libsql_ext_sqlite3_statement_column_double, 1);
|
631
|
+
|
632
|
+
rb_define_method(cLS_Statement, "column_database_name", libsql_ext_sqlite3_statement_column_database_name, 1);
|
633
|
+
rb_define_method(cLS_Statement, "column_table_name", libsql_ext_sqlite3_statement_column_table_name, 1);
|
634
|
+
rb_define_method(cLS_Statement, "column_origin_name", libsql_ext_sqlite3_statement_column_origin_name, 1);
|
635
|
+
rb_define_method(cLS_Statement, "reset!", libsql_ext_sqlite3_statement_reset, 0);
|
636
|
+
rb_define_method(cLS_Statement, "clear_bindings!", libsql_ext_sqlite3_statement_clear_bindings, 0);
|
637
|
+
rb_define_method(cLS_Statement, "parameter_count", libsql_ext_sqlite3_statement_bind_parameter_count, 0);
|
638
|
+
rb_define_method(cLS_Statement, "parameter_index", libsql_ext_sqlite3_statement_bind_parameter_index, 1);
|
639
|
+
rb_define_method(cLS_Statement, "remaining_sql", libsql_ext_sqlite3_statement_remaining_sql, 0);
|
640
|
+
rb_define_method(cLS_Statement, "bind_text", libsql_ext_sqlite3_statement_bind_text, 2);
|
641
|
+
rb_define_method(cLS_Statement, "bind_int", libsql_ext_sqlite3_statement_bind_int, 2);
|
642
|
+
rb_define_method(cLS_Statement, "bind_int64", libsql_ext_sqlite3_statement_bind_int64, 2);
|
643
|
+
rb_define_method(cLS_Statement, "bind_double", libsql_ext_sqlite3_statement_bind_double, 2);
|
644
|
+
rb_define_method(cLS_Statement, "bind_null", libsql_ext_sqlite3_statement_bind_null, 1);
|
645
|
+
rb_define_method(cLS_Statement, "bind_blob", libsql_ext_sqlite3_statement_bind_blob, 2);
|
646
|
+
rb_define_method(cLS_Statement, "bind_zeroblob", libsql_ext_sqlite3_statement_bind_zeroblob, 2);
|
647
|
+
}
|
648
|
+
|
649
|
+
|