ruby-ladybug 0.1.0
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
- checksums.yaml.gz.sig +0 -0
- data/History.md +9 -0
- data/LICENSE.txt +20 -0
- data/README.md +250 -0
- data/ext/ladybug_ext/config.c +318 -0
- data/ext/ladybug_ext/connection.c +331 -0
- data/ext/ladybug_ext/database.c +197 -0
- data/ext/ladybug_ext/extconf.rb +20 -0
- data/ext/ladybug_ext/ladybug_ext.c +158 -0
- data/ext/ladybug_ext/ladybug_ext.h +132 -0
- data/ext/ladybug_ext/node.c +24 -0
- data/ext/ladybug_ext/prepared_statement.c +396 -0
- data/ext/ladybug_ext/query_summary.c +140 -0
- data/ext/ladybug_ext/recursive_rel.c +24 -0
- data/ext/ladybug_ext/rel.c +24 -0
- data/ext/ladybug_ext/result.c +514 -0
- data/ext/ladybug_ext/types.c +619 -0
- data/lib/ladybug/config.rb +70 -0
- data/lib/ladybug/connection.rb +51 -0
- data/lib/ladybug/database.rb +53 -0
- data/lib/ladybug/node.rb +46 -0
- data/lib/ladybug/prepared_statement.rb +44 -0
- data/lib/ladybug/query_summary.rb +28 -0
- data/lib/ladybug/recursive_rel.rb +37 -0
- data/lib/ladybug/rel.rb +57 -0
- data/lib/ladybug/result.rb +196 -0
- data/lib/ladybug.rb +89 -0
- data/spec/ladybug/config_spec.rb +98 -0
- data/spec/ladybug/connection_spec.rb +36 -0
- data/spec/ladybug/database_spec.rb +57 -0
- data/spec/ladybug/prepared_statement_spec.rb +91 -0
- data/spec/ladybug/query_summary_spec.rb +30 -0
- data/spec/ladybug/result_spec.rb +225 -0
- data/spec/ladybug/types_spec.rb +285 -0
- data/spec/ladybug_spec.rb +83 -0
- data/spec/spec_helper.rb +101 -0
- data.tar.gz.sig +0 -0
- metadata +177 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* rel.c - Ladybug::Rel (relationship) class
|
|
3
|
+
*
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
#include "ladybug_ext.h"
|
|
7
|
+
|
|
8
|
+
VALUE rlbug_cLadybugRel;
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* Document-class: Ladybug::Rel
|
|
13
|
+
*/
|
|
14
|
+
void
|
|
15
|
+
rlbug_init_rel( void )
|
|
16
|
+
{
|
|
17
|
+
#ifdef FOR_RDOC
|
|
18
|
+
rlbug_mLadybug = rb_define_module( "ladybug" );
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
rlbug_cLadybugRel = rb_define_class_under( rlbug_mLadybug, "Rel", rb_cObject );
|
|
22
|
+
|
|
23
|
+
rb_require( "ladybug/rel" );
|
|
24
|
+
}
|
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* result.c - Ladybug::Result class
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#include "ladybug_ext.h"
|
|
6
|
+
|
|
7
|
+
#define CHECK_RESULT(self) ((rlbug_query_result *)rb_check_typeddata((self), &rlbug_result_type))
|
|
8
|
+
// #define DEBUG_GC(msg, ptr) fprintf( stderr, msg, ptr )
|
|
9
|
+
#define DEBUG_GC(msg, ptr)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
VALUE rlbug_cLadybugResult;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
static void rlbug_result_free( void * );
|
|
16
|
+
static void rlbug_result_mark( void * );
|
|
17
|
+
|
|
18
|
+
static const rb_data_type_t rlbug_result_type = {
|
|
19
|
+
.wrap_struct_name = "Ladybug::Result",
|
|
20
|
+
.function = {
|
|
21
|
+
.dfree = rlbug_result_free,
|
|
22
|
+
.dmark = rlbug_result_mark,
|
|
23
|
+
},
|
|
24
|
+
.data = NULL,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* Fetch function
|
|
30
|
+
*/
|
|
31
|
+
rlbug_query_result *
|
|
32
|
+
rlbug_get_result( VALUE result_obj )
|
|
33
|
+
{
|
|
34
|
+
rlbug_query_result *res = CHECK_RESULT( result_obj );
|
|
35
|
+
|
|
36
|
+
if ( res->finished ) {
|
|
37
|
+
DEBUG_GC( "XXX Getting a FINISHED result %p\n", res );
|
|
38
|
+
rb_raise( rlbug_eFinishedError, "result has been finished.\n" );
|
|
39
|
+
} else {
|
|
40
|
+
DEBUG_GC( ">>> Result %p is NOT finished.\n", res );
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return res;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
/*
|
|
48
|
+
* Allocation function
|
|
49
|
+
*/
|
|
50
|
+
static rlbug_query_result *
|
|
51
|
+
rlbug_result_alloc( void )
|
|
52
|
+
{
|
|
53
|
+
rlbug_query_result *ptr = ALLOC( rlbug_query_result );
|
|
54
|
+
|
|
55
|
+
ptr->connection = Qnil;
|
|
56
|
+
ptr->query = Qnil;
|
|
57
|
+
ptr->statement = Qnil;
|
|
58
|
+
ptr->previous_result = Qnil;
|
|
59
|
+
ptr->next_result = Qnil;
|
|
60
|
+
ptr->finished = false;
|
|
61
|
+
|
|
62
|
+
return ptr;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
* dmark function
|
|
68
|
+
*/
|
|
69
|
+
static void
|
|
70
|
+
rlbug_result_mark( void *ptr )
|
|
71
|
+
{
|
|
72
|
+
rlbug_query_result *result = (rlbug_query_result *)ptr;
|
|
73
|
+
|
|
74
|
+
if ( ptr ) {
|
|
75
|
+
rb_gc_mark( result->connection );
|
|
76
|
+
rb_gc_mark( result->query );
|
|
77
|
+
rb_gc_mark( result->statement );
|
|
78
|
+
rb_gc_mark( result->previous_result );
|
|
79
|
+
rb_gc_mark( result->next_result );
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
* dfree function
|
|
86
|
+
*/
|
|
87
|
+
static void
|
|
88
|
+
rlbug_result_free( void *ptr )
|
|
89
|
+
{
|
|
90
|
+
if ( ptr ) {
|
|
91
|
+
rlbug_query_result *result = (rlbug_query_result *)ptr;
|
|
92
|
+
|
|
93
|
+
// Can't lbug_query_result_destroy here because the database or connection
|
|
94
|
+
// might already have been destroyed.
|
|
95
|
+
|
|
96
|
+
/*
|
|
97
|
+
lbug_query_result *i_result = &result->result;
|
|
98
|
+
|
|
99
|
+
if ( i_result->_is_owned_by_cpp != NULL ) {
|
|
100
|
+
DEBUG_GC( ">>> destroying query_result %p\n", ptr );
|
|
101
|
+
lbug_query_result_destroy( i_result );
|
|
102
|
+
}
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
if ( !result->finished ) {
|
|
106
|
+
DEBUG_GC( "*** Possibly leaking result %p\n", result );
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
DEBUG_GC( ">>> Freeing result %p\n", ptr );
|
|
110
|
+
xfree( ptr );
|
|
111
|
+
ptr = NULL;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
/*
|
|
117
|
+
* ::allocate function
|
|
118
|
+
*/
|
|
119
|
+
static VALUE
|
|
120
|
+
rlbug_result_s_allocate( VALUE klass )
|
|
121
|
+
{
|
|
122
|
+
return TypedData_Wrap_Struct( klass, &rlbug_result_type, NULL );
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
VALUE
|
|
127
|
+
rlbug_result_from_query( VALUE klass, VALUE connection, VALUE query, lbug_query_result result )
|
|
128
|
+
{
|
|
129
|
+
rlbug_query_result *ptr = rlbug_result_alloc();
|
|
130
|
+
DEBUG_GC( ">>> allocated result %p\n", ptr );
|
|
131
|
+
|
|
132
|
+
VALUE result_obj = rb_class_new_instance( 0, 0, klass );
|
|
133
|
+
RTYPEDDATA_DATA( result_obj ) = ptr;
|
|
134
|
+
|
|
135
|
+
ptr->connection = connection;
|
|
136
|
+
ptr->query = query;
|
|
137
|
+
ptr->result = result;
|
|
138
|
+
|
|
139
|
+
return result_obj;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
VALUE
|
|
144
|
+
rlbug_result_from_prepared_statement( VALUE klass, VALUE connection, VALUE statement, lbug_query_result result )
|
|
145
|
+
{
|
|
146
|
+
rlbug_query_result *ptr = rlbug_result_alloc();
|
|
147
|
+
DEBUG_GC( ">>> allocated result %p\n", ptr );
|
|
148
|
+
|
|
149
|
+
VALUE result_obj = rb_class_new_instance( 0, 0, klass );
|
|
150
|
+
RTYPEDDATA_DATA( result_obj ) = ptr;
|
|
151
|
+
|
|
152
|
+
ptr->connection = connection;
|
|
153
|
+
ptr->statement = statement;
|
|
154
|
+
ptr->result = result;
|
|
155
|
+
|
|
156
|
+
return result_obj;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
/*
|
|
162
|
+
* call-seq:
|
|
163
|
+
* Ladybug::Result.from_next_set( result ) -> result2
|
|
164
|
+
*
|
|
165
|
+
* Return a Ladybug::Result for the next result set after the specified +result+.
|
|
166
|
+
* Returns `nil` if there is no next result set..
|
|
167
|
+
*
|
|
168
|
+
*/
|
|
169
|
+
static VALUE
|
|
170
|
+
rlbug_result_s_from_next_set( VALUE klass, VALUE result )
|
|
171
|
+
{
|
|
172
|
+
rlbug_query_result *start_result = rlbug_get_result( result );
|
|
173
|
+
rlbug_query_result *next_result;
|
|
174
|
+
VALUE result_obj;
|
|
175
|
+
|
|
176
|
+
if ( RTEST(start_result->next_result) ) {
|
|
177
|
+
return start_result->next_result;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if ( !lbug_query_result_has_next_query_result(&start_result->result) ) {
|
|
181
|
+
return Qnil;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
next_result = rlbug_result_alloc();
|
|
185
|
+
|
|
186
|
+
if ( lbug_query_result_get_next_query_result(&start_result->result, &next_result->result) != LbugSuccess ) {
|
|
187
|
+
char *err_detail = lbug_query_result_get_error_message( &next_result->result );
|
|
188
|
+
char errmsg[ 4096 ] = "\0";
|
|
189
|
+
|
|
190
|
+
snprintf( errmsg, 4096, "Could not fetch next query result set: %s.", err_detail );
|
|
191
|
+
|
|
192
|
+
xfree( next_result );
|
|
193
|
+
next_result = NULL;
|
|
194
|
+
lbug_destroy_string( err_detail );
|
|
195
|
+
|
|
196
|
+
rb_raise( rlbug_eQueryError, "%s", errmsg );
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
DEBUG_GC( ">>> allocated result %p\n", next_result );
|
|
200
|
+
|
|
201
|
+
result_obj = rb_class_new_instance( 0, 0, klass );
|
|
202
|
+
RTYPEDDATA_DATA( result_obj ) = next_result;
|
|
203
|
+
|
|
204
|
+
next_result->connection = start_result->connection;
|
|
205
|
+
next_result->previous_result = result;
|
|
206
|
+
|
|
207
|
+
start_result->next_result = result_obj;
|
|
208
|
+
|
|
209
|
+
return result_obj;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
/*
|
|
214
|
+
* call-seq:
|
|
215
|
+
* result.success? -> true or false
|
|
216
|
+
*
|
|
217
|
+
* Returns true if the query is executed successful, false otherwise.
|
|
218
|
+
*
|
|
219
|
+
*/
|
|
220
|
+
static VALUE
|
|
221
|
+
rlbug_result_success_p( VALUE self )
|
|
222
|
+
{
|
|
223
|
+
rlbug_query_result *result = rlbug_get_result( self );
|
|
224
|
+
|
|
225
|
+
if ( lbug_query_result_is_success(&result->result) ) {
|
|
226
|
+
return Qtrue;
|
|
227
|
+
} else {
|
|
228
|
+
return Qfalse;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
/*
|
|
234
|
+
* call-seq:
|
|
235
|
+
* result.num_columns -> integer
|
|
236
|
+
*
|
|
237
|
+
* Returns the number of columns in the query result.
|
|
238
|
+
*
|
|
239
|
+
*/
|
|
240
|
+
static VALUE
|
|
241
|
+
rlbug_result_num_columns( VALUE self )
|
|
242
|
+
{
|
|
243
|
+
rlbug_query_result *result = rlbug_get_result( self );
|
|
244
|
+
const uint64_t count = lbug_query_result_get_num_columns( &result->result );
|
|
245
|
+
|
|
246
|
+
return ULONG2NUM( count );
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
/*
|
|
251
|
+
* call-seq:
|
|
252
|
+
* result.num_tuples -> integer
|
|
253
|
+
*
|
|
254
|
+
* Returns the number of tuples in the query result.
|
|
255
|
+
*
|
|
256
|
+
*/
|
|
257
|
+
static VALUE
|
|
258
|
+
rlbug_result_num_tuples( VALUE self )
|
|
259
|
+
{
|
|
260
|
+
rlbug_query_result *result = rlbug_get_result( self );
|
|
261
|
+
const uint64_t count = lbug_query_result_get_num_tuples( &result->result );
|
|
262
|
+
|
|
263
|
+
return ULONG2NUM( count );
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
/*
|
|
268
|
+
* call-seq:
|
|
269
|
+
* result.to_s -> string
|
|
270
|
+
*
|
|
271
|
+
* Returns the result as a String.
|
|
272
|
+
*
|
|
273
|
+
*/
|
|
274
|
+
static VALUE
|
|
275
|
+
rlbug_result_to_s( VALUE self )
|
|
276
|
+
{
|
|
277
|
+
rlbug_query_result *result = rlbug_get_result( self );
|
|
278
|
+
char *string = lbug_query_result_to_string( &result->result );
|
|
279
|
+
|
|
280
|
+
VALUE rval = rb_str_new2( string );
|
|
281
|
+
lbug_destroy_string( string );
|
|
282
|
+
|
|
283
|
+
return rval;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
/*
|
|
288
|
+
* call-seq:
|
|
289
|
+
* result.has_next? -> true or false
|
|
290
|
+
*
|
|
291
|
+
* Returns true if we have not consumed all tuples in the query result, false
|
|
292
|
+
* otherwise.
|
|
293
|
+
*
|
|
294
|
+
*/
|
|
295
|
+
static VALUE
|
|
296
|
+
rlbug_result_has_next_p( VALUE self )
|
|
297
|
+
{
|
|
298
|
+
rlbug_query_result *result = rlbug_get_result( self );
|
|
299
|
+
|
|
300
|
+
if ( lbug_query_result_has_next(&result->result) ) {
|
|
301
|
+
return Qtrue;
|
|
302
|
+
} else {
|
|
303
|
+
return Qfalse;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
/*
|
|
309
|
+
* call-seq:
|
|
310
|
+
* result.has_next_set? -> true or false
|
|
311
|
+
*
|
|
312
|
+
* Returns true if there was more than one result set in the results, and
|
|
313
|
+
* the current set is not the last one. You can call #next_set to move on to
|
|
314
|
+
* the next result set.
|
|
315
|
+
*
|
|
316
|
+
*/
|
|
317
|
+
static VALUE
|
|
318
|
+
rlbug_result_has_next_set_p( VALUE self )
|
|
319
|
+
{
|
|
320
|
+
rlbug_query_result *result = rlbug_get_result( self );
|
|
321
|
+
|
|
322
|
+
if ( lbug_query_result_has_next_query_result(&result->result) ) {
|
|
323
|
+
return Qtrue;
|
|
324
|
+
} else {
|
|
325
|
+
return Qfalse;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
/*
|
|
331
|
+
* call-seq:
|
|
332
|
+
* result.reset_iterator
|
|
333
|
+
*
|
|
334
|
+
* Resets the iterator of the query result to the beginning.
|
|
335
|
+
*
|
|
336
|
+
*/
|
|
337
|
+
static VALUE
|
|
338
|
+
rlbug_result_reset_iterator( VALUE self )
|
|
339
|
+
{
|
|
340
|
+
rlbug_query_result *result = rlbug_get_result( self );
|
|
341
|
+
lbug_query_result_reset_iterator( &result->result );
|
|
342
|
+
return Qtrue;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
/*
|
|
347
|
+
* call-seq:
|
|
348
|
+
* result.get_next_values
|
|
349
|
+
*
|
|
350
|
+
* Returns the next tuple of the query result values if there is one, otherwise
|
|
351
|
+
* returns `nil`.
|
|
352
|
+
*
|
|
353
|
+
*/
|
|
354
|
+
static VALUE
|
|
355
|
+
rlbug_result_get_next_values( VALUE self )
|
|
356
|
+
{
|
|
357
|
+
rlbug_query_result *result = rlbug_get_result( self );
|
|
358
|
+
lbug_flat_tuple tuple;
|
|
359
|
+
lbug_logical_type column_type;
|
|
360
|
+
lbug_value column_value;
|
|
361
|
+
uint64_t column_count = lbug_query_result_get_num_columns( &result->result );
|
|
362
|
+
VALUE current_value = Qnil,
|
|
363
|
+
rval = rb_ary_new();
|
|
364
|
+
|
|
365
|
+
if ( !lbug_query_result_has_next(&result->result) ) {
|
|
366
|
+
return Qnil;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if ( lbug_query_result_get_next(&result->result, &tuple) != LbugSuccess ) {
|
|
370
|
+
char *err_detail = lbug_query_result_get_error_message( &result->result );
|
|
371
|
+
char errmsg[ 4096 ] = "\0";
|
|
372
|
+
|
|
373
|
+
snprintf( errmsg, 4096, "Could not fetch next tuple: %s.", err_detail );
|
|
374
|
+
|
|
375
|
+
lbug_destroy_string( err_detail );
|
|
376
|
+
|
|
377
|
+
rb_raise( rlbug_eQueryError, "%s", errmsg );
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
for ( uint64_t i = 0 ; i < column_count ; i++ ) {
|
|
381
|
+
lbug_query_result_get_column_data_type( &result->result, i, &column_type );
|
|
382
|
+
lbug_flat_tuple_get_value( &tuple, i, &column_value );
|
|
383
|
+
|
|
384
|
+
current_value = rlbug_convert_logical_lbug_value_to_ruby( &column_type, &column_value );
|
|
385
|
+
rb_ary_push( rval, current_value );
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
lbug_flat_tuple_destroy( &tuple );
|
|
389
|
+
|
|
390
|
+
return rval;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
/*
|
|
395
|
+
* call-seq:
|
|
396
|
+
* result.get_column_names
|
|
397
|
+
*
|
|
398
|
+
* Returns the names of the columns of the results as an Array of Strings.
|
|
399
|
+
*
|
|
400
|
+
*/
|
|
401
|
+
static VALUE
|
|
402
|
+
rlbug_result_get_column_names( VALUE self )
|
|
403
|
+
{
|
|
404
|
+
rlbug_query_result *result = rlbug_get_result( self );
|
|
405
|
+
uint64_t col_count = lbug_query_result_get_num_columns( &result->result );
|
|
406
|
+
char *name;
|
|
407
|
+
VALUE rval = rb_ary_new();
|
|
408
|
+
|
|
409
|
+
for ( uint64_t i = 0 ; i < col_count ; i++ ) {
|
|
410
|
+
if ( lbug_query_result_get_column_name(&result->result, i, &name) != LbugSuccess ) {
|
|
411
|
+
rb_raise( rlbug_eError, "couldn't fetch name of column %llu", i );
|
|
412
|
+
}
|
|
413
|
+
rb_ary_push( rval, rb_str_new2(name) );
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
return rval;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
/*
|
|
421
|
+
* call-seq:
|
|
422
|
+
* result.finish
|
|
423
|
+
*
|
|
424
|
+
* Discard a result and free up its memory. An exception is raised if the result
|
|
425
|
+
* is used after this call.
|
|
426
|
+
*
|
|
427
|
+
*/
|
|
428
|
+
static VALUE
|
|
429
|
+
rlbug_result_finish( VALUE self )
|
|
430
|
+
{
|
|
431
|
+
rlbug_query_result *result = CHECK_RESULT( self );
|
|
432
|
+
lbug_query_result *i_result = &result->result;
|
|
433
|
+
VALUE related_res;
|
|
434
|
+
|
|
435
|
+
if ( !result->finished ) {
|
|
436
|
+
DEBUG_GC( ">>> Finishing %p\n", result );
|
|
437
|
+
result->finished = true;
|
|
438
|
+
if ( i_result->_query_result != NULL ) {
|
|
439
|
+
lbug_query_result_destroy( i_result );
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if ( RTEST(result->previous_result) ) {
|
|
443
|
+
related_res = result->previous_result;
|
|
444
|
+
result->previous_result = Qnil;
|
|
445
|
+
rb_funcall( related_res, rb_intern("finish"), 0 );
|
|
446
|
+
}
|
|
447
|
+
if ( RTEST(result->next_result) ) {
|
|
448
|
+
related_res = result->next_result;
|
|
449
|
+
result->next_result = Qnil;
|
|
450
|
+
rb_funcall( related_res, rb_intern("finish"), 0 );
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
return Qtrue;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
/*
|
|
459
|
+
* call-seq:
|
|
460
|
+
* result.finished? -> true or false
|
|
461
|
+
*
|
|
462
|
+
* Returns +true+ if the receiver has been finished.
|
|
463
|
+
*
|
|
464
|
+
*/
|
|
465
|
+
static VALUE
|
|
466
|
+
rlbug_result_finished_p( VALUE self )
|
|
467
|
+
{
|
|
468
|
+
rlbug_query_result *result = CHECK_RESULT( self );
|
|
469
|
+
if ( result->finished ) {
|
|
470
|
+
return Qtrue;
|
|
471
|
+
} else {
|
|
472
|
+
return Qfalse;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
/*
|
|
478
|
+
* Document-class: Ladybug::Result
|
|
479
|
+
*/
|
|
480
|
+
void
|
|
481
|
+
rlbug_init_result( void )
|
|
482
|
+
{
|
|
483
|
+
#ifdef FOR_RDOC
|
|
484
|
+
rlbug_mLadybug = rb_define_module( "ladybug" );
|
|
485
|
+
#endif
|
|
486
|
+
|
|
487
|
+
rlbug_cLadybugResult = rb_define_class_under( rlbug_mLadybug, "Result", rb_cObject );
|
|
488
|
+
|
|
489
|
+
VALUE enumerable = rb_const_get( rb_cObject, rb_intern("Enumerable") );
|
|
490
|
+
rb_include_module( rlbug_cLadybugResult, enumerable );
|
|
491
|
+
|
|
492
|
+
rb_define_alloc_func( rlbug_cLadybugResult, rlbug_result_s_allocate );
|
|
493
|
+
rb_undef_method( CLASS_OF(rlbug_cLadybugResult), "new" );
|
|
494
|
+
|
|
495
|
+
rb_define_singleton_method( rlbug_cLadybugResult, "from_next_set", rlbug_result_s_from_next_set, 1 );
|
|
496
|
+
|
|
497
|
+
rb_define_method( rlbug_cLadybugResult, "success?", rlbug_result_success_p, 0 );
|
|
498
|
+
|
|
499
|
+
rb_define_method( rlbug_cLadybugResult, "num_columns", rlbug_result_num_columns, 0 );
|
|
500
|
+
rb_define_method( rlbug_cLadybugResult, "num_tuples", rlbug_result_num_tuples, 0 );
|
|
501
|
+
rb_define_method( rlbug_cLadybugResult, "to_s", rlbug_result_to_s, 0 );
|
|
502
|
+
|
|
503
|
+
rb_define_method( rlbug_cLadybugResult, "has_next?", rlbug_result_has_next_p, 0 );
|
|
504
|
+
rb_define_method( rlbug_cLadybugResult, "has_next_set?", rlbug_result_has_next_set_p, 0 );
|
|
505
|
+
|
|
506
|
+
rb_define_method( rlbug_cLadybugResult, "reset_iterator", rlbug_result_reset_iterator, 0 );
|
|
507
|
+
rb_define_method( rlbug_cLadybugResult, "get_next_values", rlbug_result_get_next_values, 0 );
|
|
508
|
+
rb_define_method( rlbug_cLadybugResult, "get_column_names", rlbug_result_get_column_names, 0 );
|
|
509
|
+
|
|
510
|
+
rb_define_method( rlbug_cLadybugResult, "finish", rlbug_result_finish, 0 );
|
|
511
|
+
rb_define_method( rlbug_cLadybugResult, "finished?", rlbug_result_finished_p, 0 );
|
|
512
|
+
|
|
513
|
+
rb_require( "ladybug/result" );
|
|
514
|
+
}
|