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.
@@ -0,0 +1,132 @@
1
+ /*
2
+ * ladybug_ext.h - Ruby binding for LadybugDB
3
+ *
4
+ * Authors:
5
+ * * Michael Granger <ged@FaerieMUD.org>
6
+ *
7
+ */
8
+
9
+ #ifndef LBUG_EXT_H_AA9CC4A5
10
+ #define LBUG_EXT_H_AA9CC4A5
11
+
12
+ #include "extconf.h"
13
+
14
+ #include <ruby.h>
15
+ #include <ruby/encoding.h>
16
+ #include <ruby/intern.h>
17
+ #include <ruby/thread.h>
18
+ #include <ruby/version.h>
19
+
20
+ #include <stdbool.h>
21
+
22
+ #include "lbug.h"
23
+
24
+ /* --------------------------------------------------------------
25
+ * Declarations
26
+ * -------------------------------------------------------------- */
27
+
28
+ #ifdef HAVE_STDARG_PROTOTYPES
29
+ #include <stdarg.h>
30
+ #define va_init_list(a, b) va_start (a, b)
31
+ void rlbug_log_obj (VALUE, const char *, const char *, ...)
32
+ __attribute__ ((format (printf, 2, 0)));
33
+ void rlbug_log (const char *, const char *, ...)
34
+ __attribute__ ((format (printf, 1, 0)));
35
+ #else
36
+ #include <varargs.h>
37
+ #define va_init_list(a, b) va_start (a)
38
+ void rlbug_log_obj (VALUE, const char *, const char *, va_dcl);
39
+ void rlbug_log (const char *, const char *, va_dcl);
40
+ #endif
41
+
42
+ /* --------------------------------------------------------------
43
+ * Structs
44
+ * -------------------------------------------------------------- */
45
+
46
+ typedef struct {
47
+ lbug_database db;
48
+ VALUE path;
49
+ VALUE config;
50
+ } rlbug_database;
51
+
52
+ typedef struct {
53
+ lbug_connection conn;
54
+ VALUE database;
55
+ VALUE queries;
56
+ VALUE statements;
57
+ } rlbug_connection;
58
+
59
+ typedef struct {
60
+ lbug_query_result result;
61
+ VALUE connection;
62
+ VALUE query;
63
+ VALUE statement;
64
+ VALUE previous_result;
65
+ VALUE next_result;
66
+ bool finished;
67
+ } rlbug_query_result;
68
+
69
+ typedef struct {
70
+ lbug_prepared_statement statement;
71
+ VALUE connection;
72
+ VALUE query;
73
+ bool finished;
74
+ } rlbug_prepared_statement;
75
+
76
+
77
+ /* -------------------------------------------------------
78
+ * Globals
79
+ * ------------------------------------------------------- */
80
+
81
+ // Modules and classes
82
+ extern VALUE rlbug_mLadybug;
83
+ extern VALUE rlbug_cLadybugDatabase;
84
+ extern VALUE rlbug_cLadybugConfig;
85
+ extern VALUE rlbug_cLadybugConnection;
86
+ extern VALUE rlbug_cLadybugPreparedStatement;
87
+ extern VALUE rlbug_cLadybugResult;
88
+ extern VALUE rlbug_cLadybugQuerySummary;
89
+ extern VALUE rlbug_cLadybugNode;
90
+ extern VALUE rlbug_cLadybugRecursiveRel;
91
+ extern VALUE rlbug_cLadybugRel;
92
+
93
+ // Exception types
94
+ extern VALUE rlbug_eError;
95
+ extern VALUE rlbug_eDatabaseError;
96
+ extern VALUE rlbug_eConnectionError;
97
+ extern VALUE rlbug_eQueryError;
98
+ extern VALUE rlbug_eFinishedError;
99
+
100
+ // Internal refs to external classes
101
+ extern VALUE rlbug_rb_cDate;
102
+ extern VALUE rlbug_rb_cOstruct;
103
+
104
+
105
+ /* -------------------------------------------------------
106
+ * Initializer functions
107
+ * ------------------------------------------------------- */
108
+ extern void Init_ladybug_ext _ ((void));
109
+
110
+ extern void rlbug_init_database _ ((void));
111
+ extern void rlbug_init_config _ ((void));
112
+ extern void rlbug_init_connection _ ((void));
113
+ extern void rlbug_init_prepared_statement _ ((void));
114
+ extern void rlbug_init_result _ ((void));
115
+ extern void rlbug_init_query_summary _ ((void));
116
+ extern void rlbug_init_node _ ((void));
117
+ extern void rlbug_init_rel _ ((void));
118
+ extern void rlbug_init_recursive_rel _ ((void));
119
+
120
+ extern rlbug_database *rlbug_get_database _ ((VALUE));
121
+ extern lbug_system_config *rlbug_get_config _ ((VALUE));
122
+ extern rlbug_connection *rlbug_get_connection _ ((VALUE));
123
+ extern rlbug_prepared_statement *rlbug_get_prepared_statement _ ((VALUE));
124
+ extern rlbug_query_result *rlbug_get_result _ ((VALUE));
125
+
126
+ extern VALUE rlbug_convert_lbug_value_to_ruby _ ((lbug_data_type_id, lbug_value *));
127
+ extern VALUE rlbug_convert_logical_lbug_value_to_ruby _ ((lbug_logical_type *, lbug_value *));
128
+ extern VALUE rlbug_value_to_ruby _ (( lbug_value * ));
129
+ extern VALUE rlbug_result_from_query _ ((VALUE, VALUE, VALUE, lbug_query_result));
130
+ extern VALUE rlbug_result_from_prepared_statement _ ((VALUE, VALUE, VALUE, lbug_query_result));
131
+
132
+ #endif /* end of include guard: LBUG_EXT_H_AA9CC4A5 */
@@ -0,0 +1,24 @@
1
+ /*
2
+ * node.c - Ladybug::Node class
3
+ *
4
+ */
5
+
6
+ #include "ladybug_ext.h"
7
+
8
+ VALUE rlbug_cLadybugNode;
9
+
10
+
11
+ /*
12
+ * Document-class: Ladybug::Node
13
+ */
14
+ void
15
+ rlbug_init_node( void )
16
+ {
17
+ #ifdef FOR_RDOC
18
+ rlbug_mLadybug = rb_define_module( "ladybug" );
19
+ #endif
20
+
21
+ rlbug_cLadybugNode = rb_define_class_under( rlbug_mLadybug, "Node", rb_cObject );
22
+
23
+ rb_require( "ladybug/node" );
24
+ }
@@ -0,0 +1,396 @@
1
+ /*
2
+ * prepared_statement.c - Ladybug::PreparedStatement class
3
+ *
4
+ */
5
+
6
+ #include "lbug.h"
7
+ #include "ladybug_ext.h"
8
+
9
+ #define CHECK_PREPARED_STATEMENT( self ) \
10
+ ((rlbug_prepared_statement *)rb_check_typeddata( (self), &rlbug_prepared_statement_type) )
11
+ // #define DEBUG_GC(msg, ptr) fprintf( stderr, msg, ptr )
12
+ #define DEBUG_GC(msg, ptr)
13
+
14
+
15
+ VALUE rlbug_cLadybugPreparedStatement;
16
+
17
+ static void rlbug_prepared_statement_free( void * );
18
+ static void rlbug_prepared_statement_mark( void * );
19
+ static void rlbug_bind_string( rlbug_prepared_statement *, const char *, VALUE );
20
+
21
+ static const rb_data_type_t rlbug_prepared_statement_type = {
22
+ .wrap_struct_name = "Ladybug::PreparedStatement",
23
+ .function = {
24
+ .dfree = rlbug_prepared_statement_free,
25
+ .dmark = rlbug_prepared_statement_mark,
26
+ },
27
+ .data = NULL,
28
+ };
29
+
30
+
31
+
32
+ /*
33
+ * Fetch function
34
+ */
35
+ rlbug_prepared_statement *
36
+ rlbug_get_prepared_statement( VALUE prepared_statement_obj )
37
+ {
38
+ return CHECK_PREPARED_STATEMENT( prepared_statement_obj );
39
+ }
40
+
41
+
42
+ /*
43
+ * Allocation function
44
+ */
45
+ static rlbug_prepared_statement *
46
+ rlbug_prepared_statement_alloc( void )
47
+ {
48
+ rlbug_prepared_statement *ptr = ALLOC( rlbug_prepared_statement );
49
+
50
+ ptr->connection = Qnil;
51
+ ptr->query = Qnil;
52
+
53
+ return ptr;
54
+ }
55
+
56
+
57
+ /*
58
+ * dmark function
59
+ */
60
+ static void
61
+ rlbug_prepared_statement_mark( void *ptr )
62
+ {
63
+ rlbug_prepared_statement *prepared_statement_s = (rlbug_prepared_statement *)ptr;
64
+
65
+ if ( ptr ) {
66
+ rb_gc_mark( prepared_statement_s->connection );
67
+ rb_gc_mark( prepared_statement_s->query );
68
+ }
69
+ }
70
+
71
+
72
+ /*
73
+ * dfree function
74
+ */
75
+ static void
76
+ rlbug_prepared_statement_free( void *ptr )
77
+ {
78
+ if ( ptr ) {
79
+ DEBUG_GC( ">>> freeing prepared statement %p\n", ptr );
80
+ // Can't lbug_prepared_statement_destroy here because the database or connection
81
+ // might already have been destroyed.
82
+ xfree( ptr );
83
+ ptr = NULL;
84
+ }
85
+ }
86
+
87
+
88
+ /*
89
+ * ::allocate function
90
+ */
91
+ static VALUE
92
+ rlbug_prepared_statement_s_allocate( VALUE klass )
93
+ {
94
+ return TypedData_Wrap_Struct( klass, &rlbug_prepared_statement_type, NULL );
95
+ }
96
+
97
+
98
+ static VALUE
99
+ rlbug_prepared_statement_initialize( VALUE self, VALUE connection, VALUE query )
100
+ {
101
+ rlbug_prepared_statement *stmt = CHECK_PREPARED_STATEMENT( self );
102
+
103
+ if ( !stmt ) {
104
+ rlbug_connection *conn = rlbug_get_connection( connection );
105
+ const char *query_s = StringValueCStr( query );
106
+
107
+ stmt = rlbug_prepared_statement_alloc();
108
+
109
+ if ( lbug_connection_prepare(&conn->conn, query_s, &stmt->statement) != LbugSuccess ) {
110
+ char *err_detail = lbug_prepared_statement_get_error_message( &stmt->statement );
111
+ char errmsg[ 4096 ] = "\0";
112
+
113
+ snprintf( errmsg, 4096, "Could not prepare query `%s': %s.", query_s, err_detail );
114
+
115
+ xfree( stmt );
116
+ stmt = NULL;
117
+ lbug_destroy_string( err_detail );
118
+
119
+ rb_raise( rlbug_eQueryError, "%s", errmsg );
120
+ }
121
+
122
+ DEBUG_GC( ">>> allocated prepared statement %p\n", stmt );
123
+ RTYPEDDATA_DATA( self ) = stmt;
124
+
125
+ stmt->connection = connection;
126
+ stmt->query = query;
127
+
128
+ } else {
129
+ rb_raise( rb_eRuntimeError, "cannot reinit prepared statement" );
130
+ }
131
+
132
+ rb_call_super( 0, 0 );
133
+
134
+ return Qtrue;
135
+ }
136
+
137
+
138
+ struct execute_call {
139
+ lbug_connection *conn;
140
+ lbug_prepared_statement *stmt;
141
+ lbug_query_result *result;
142
+ };
143
+
144
+
145
+ static void *
146
+ rlbug_connection_do_execute_without_gvl( void *ptr )
147
+ {
148
+ struct execute_call *qcall = (struct execute_call *)ptr;
149
+ lbug_state state;
150
+
151
+ state = lbug_connection_execute( qcall->conn, qcall->stmt, qcall->result );
152
+
153
+ return (void *)state;
154
+ }
155
+
156
+
157
+ static void
158
+ rlbug_connection_cancel_execute( void *ptr )
159
+ {
160
+ lbug_connection *conn = (lbug_connection *)ptr;
161
+ lbug_connection_interrupt( conn );
162
+ }
163
+
164
+
165
+ // Inner prepared statement constructor
166
+ static lbug_query_result
167
+ rlbug_prepared_statement_do_execute( VALUE self )
168
+ {
169
+ rlbug_prepared_statement *stmt = CHECK_PREPARED_STATEMENT( self );
170
+ VALUE connection = stmt->connection;
171
+ rlbug_connection *conn = rlbug_get_connection( connection );
172
+ lbug_query_result result;
173
+ struct execute_call qcall;
174
+ lbug_state execute_state;
175
+ void *result_ptr;
176
+
177
+ qcall.conn = &conn->conn;
178
+ qcall.stmt = &stmt->statement;
179
+ qcall.result = &result;
180
+
181
+ result_ptr = rb_thread_call_without_gvl(
182
+ rlbug_connection_do_execute_without_gvl, (void *)&qcall,
183
+ rlbug_connection_cancel_execute, (void *)&conn->conn );
184
+
185
+ _Pragma("GCC diagnostic push")
186
+ _Pragma("GCC diagnostic ignored \"-Wvoid-pointer-to-enum-cast\"")
187
+ execute_state = (lbug_state)result_ptr;
188
+ _Pragma("GCC diagnostic pop")
189
+
190
+ if ( execute_state != LbugSuccess ) {
191
+ char *err_detail = lbug_query_result_get_error_message( &result );
192
+ char errmsg[ 4096 ] = "\0";
193
+
194
+ snprintf( errmsg, 4096, "Could not execute prepared statement: %s.", err_detail );
195
+
196
+ lbug_destroy_string( err_detail );
197
+ lbug_query_result_destroy( &result );
198
+
199
+ rb_raise( rlbug_eQueryError, "%s", errmsg );
200
+ }
201
+
202
+ return *qcall.result;
203
+ }
204
+
205
+
206
+ static VALUE
207
+ rlbug_prepared_statement__execute( VALUE self )
208
+ {
209
+ rlbug_prepared_statement *stmt = CHECK_PREPARED_STATEMENT( self );
210
+ lbug_query_result result = rlbug_prepared_statement_do_execute( self );
211
+
212
+ return rlbug_result_from_prepared_statement( rlbug_cLadybugResult, stmt->connection, self, result );
213
+ }
214
+
215
+
216
+ static VALUE
217
+ rlbug_prepared_statement__execute_bang( VALUE self )
218
+ {
219
+ lbug_query_result result = rlbug_prepared_statement_do_execute( self );
220
+ return lbug_query_result_is_success( &result ) ? Qtrue : Qfalse;
221
+ }
222
+
223
+
224
+ /*
225
+ * call-seq:
226
+ * statement.success? -> true or false
227
+ *
228
+ * Returns +true+ if the query was prepared successfully.
229
+ *
230
+ */
231
+ static VALUE
232
+ rlbug_prepared_statement_success_p( VALUE self )
233
+ {
234
+ rlbug_prepared_statement *stmt = CHECK_PREPARED_STATEMENT( self );
235
+
236
+ if ( lbug_prepared_statement_is_success(&stmt->statement) ) {
237
+ return Qtrue;
238
+ } else {
239
+ return Qfalse;
240
+ }
241
+ }
242
+
243
+
244
+ /*
245
+ * call-seq:
246
+ * statement.bind_variable( name, value )
247
+ *
248
+ * Binds the given +value+ to the given parameter +name+ in the prepared statement
249
+ *
250
+ */
251
+ static VALUE
252
+ rlbug_prepared_statement_bind_variable( VALUE self, VALUE name, VALUE value )
253
+ {
254
+ rlbug_prepared_statement *stmt = CHECK_PREPARED_STATEMENT( self );
255
+ VALUE name_string = rb_funcall( name, rb_intern("to_s"), 0 );
256
+ const char *name_s = StringValueCStr( name_string );
257
+ lbug_value *null_value;
258
+
259
+ switch (TYPE(value)) {
260
+ case T_TRUE:
261
+ case T_FALSE:
262
+ lbug_prepared_statement_bind_bool( &stmt->statement, name_s, RTEST(value) );
263
+ break;
264
+
265
+ // fallthrough
266
+ case T_FLOAT:
267
+ lbug_prepared_statement_bind_float( &stmt->statement, name_s, NUM2DBL(value) );
268
+ break;
269
+
270
+ case T_BIGNUM:
271
+ lbug_prepared_statement_bind_int64( &stmt->statement, name_s, NUM2LL(value) );
272
+ break;
273
+
274
+ case T_FIXNUM:
275
+ lbug_prepared_statement_bind_int32( &stmt->statement, name_s, NUM2INT(value) );
276
+ break;
277
+
278
+ case T_SYMBOL:
279
+ rb_notimplement();
280
+ break; // not reached
281
+
282
+ case T_NIL:
283
+ null_value = lbug_value_create_null();
284
+ lbug_prepared_statement_bind_value( &stmt->statement, name_s, null_value );
285
+ lbug_value_destroy( null_value );
286
+ break;
287
+
288
+ case T_OBJECT:
289
+ case T_CLASS:
290
+ case T_MODULE:
291
+ case T_REGEXP:
292
+ case T_ARRAY:
293
+ case T_HASH:
294
+ case T_STRUCT:
295
+ case T_COMPLEX:
296
+ case T_RATIONAL:
297
+ case T_FILE:
298
+ case T_DATA:
299
+ case T_STRING:
300
+ default:
301
+ rlbug_bind_string( stmt, name_s, value );
302
+ break;
303
+
304
+ // lbug_prepared_statement_bind_int8
305
+ // lbug_prepared_statement_bind_int16
306
+ // lbug_prepared_statement_bind_uint64
307
+ // lbug_prepared_statement_bind_uint32
308
+ // lbug_prepared_statement_bind_uint16
309
+ // lbug_prepared_statement_bind_uint8
310
+
311
+ // lbug_prepared_statement_bind_double
312
+ // lbug_prepared_statement_bind_date
313
+ // lbug_prepared_statement_bind_timestamp_ns
314
+ // lbug_prepared_statement_bind_timestamp_sec
315
+ // lbug_prepared_statement_bind_timestamp_tz
316
+ // lbug_prepared_statement_bind_timestamp_ms
317
+ // lbug_prepared_statement_bind_timestamp
318
+ // lbug_prepared_statement_bind_interval
319
+ // lbug_prepared_statement_bind_value
320
+ }
321
+
322
+ return Qtrue;
323
+ }
324
+
325
+
326
+ static void
327
+ rlbug_bind_string( rlbug_prepared_statement *stmt, const char *name_s, VALUE value )
328
+ {
329
+ const char *value_s = StringValueCStr( value );
330
+ lbug_prepared_statement_bind_string( &stmt->statement, name_s, value_s );
331
+ }
332
+
333
+
334
+ /*
335
+ * call-seq:
336
+ * statement.connection -> conn
337
+ *
338
+ * Return the Ladybug::Connection used to run this statement.
339
+ *
340
+ */
341
+ static VALUE
342
+ rlbug_prepared_statement_connection( VALUE self )
343
+ {
344
+ rlbug_prepared_statement *statement_s = rlbug_get_prepared_statement( self );
345
+ return statement_s->connection;
346
+ }
347
+
348
+
349
+ /*
350
+ * call-seq:
351
+ * statement.query -> string
352
+ *
353
+ * Return the query string used to build this statement.
354
+ *
355
+ */
356
+ static VALUE
357
+ rlbug_prepared_statement_query( VALUE self )
358
+ {
359
+ rlbug_prepared_statement *statement_s = rlbug_get_prepared_statement( self );
360
+ return statement_s->query;
361
+ }
362
+
363
+
364
+
365
+ /*
366
+ * Document-class: Ladybug::PreparedStatement
367
+ */
368
+ void
369
+ rlbug_init_prepared_statement( void )
370
+ {
371
+ #ifdef FOR_RDOC
372
+ rlbug_mLadybug = rb_define_module( "ladybug" );
373
+ #endif
374
+
375
+ rlbug_cLadybugPreparedStatement = rb_define_class_under( rlbug_mLadybug, "PreparedStatement", rb_cObject );
376
+
377
+ rb_define_alloc_func( rlbug_cLadybugPreparedStatement, rlbug_prepared_statement_s_allocate );
378
+
379
+ rb_define_protected_method( rlbug_cLadybugPreparedStatement, "initialize",
380
+ rlbug_prepared_statement_initialize, 2 );
381
+ rb_define_protected_method( rlbug_cLadybugPreparedStatement, "_execute",
382
+ rlbug_prepared_statement__execute, 0 );
383
+ rb_define_protected_method( rlbug_cLadybugPreparedStatement, "_execute!",
384
+ rlbug_prepared_statement__execute_bang, 0 );
385
+
386
+ rb_define_method( rlbug_cLadybugPreparedStatement, "connection",
387
+ rlbug_prepared_statement_connection, 0 );
388
+ rb_define_method( rlbug_cLadybugPreparedStatement, "query",
389
+ rlbug_prepared_statement_query, 0 );
390
+
391
+ rb_define_method( rlbug_cLadybugPreparedStatement, "success?", rlbug_prepared_statement_success_p, 0 );
392
+ rb_define_method( rlbug_cLadybugPreparedStatement, "bind_variable",
393
+ rlbug_prepared_statement_bind_variable, 2 );
394
+
395
+ rb_require( "ladybug/prepared_statement" );
396
+ }
@@ -0,0 +1,140 @@
1
+ /*
2
+ * query_summary.c - Ladybug::QuerySummary class
3
+ *
4
+ */
5
+
6
+ #include "ladybug_ext.h"
7
+
8
+ #define CHECK_QUERY_SUMMARY(self) \
9
+ ((lbug_query_summary*)rb_check_typeddata((self), &rlbug_query_summary_type))
10
+ // #define DEBUG_GC(msg, ptr) fprintf( stderr, msg, ptr )
11
+ #define DEBUG_GC(msg, ptr)
12
+
13
+
14
+ VALUE rlbug_cLadybugQuerySummary;
15
+
16
+ static void rlbug_query_summary_free( void * );
17
+
18
+ static const rb_data_type_t rlbug_query_summary_type = {
19
+ .wrap_struct_name = "Ladybug::QuerySummary",
20
+ .function = {
21
+ .dfree = rlbug_query_summary_free,
22
+ },
23
+ .data = NULL,
24
+ };
25
+
26
+
27
+ static void
28
+ rlbug_query_summary_free( void *ptr )
29
+ {
30
+ lbug_query_summary *query_summary = (lbug_query_summary *)ptr;
31
+
32
+ if ( ptr ) {
33
+ DEBUG_GC( ">>> freeing query summary %p\n", ptr );
34
+ lbug_query_summary_destroy( query_summary );
35
+ xfree( ptr );
36
+ }
37
+ }
38
+
39
+
40
+ /*
41
+ * ::allocate function
42
+ */
43
+ static VALUE
44
+ rlbug_query_summary_s_allocate( VALUE klass )
45
+ {
46
+ return TypedData_Wrap_Struct( klass, &rlbug_query_summary_type, NULL );
47
+ }
48
+
49
+
50
+ /*
51
+ * call-seq:
52
+ * Ladybug::QuerySummary.from_result( result ) -> query_summary
53
+ *
54
+ * Return a Ladybug::QuerySummary from a Ladybug::Result.
55
+ *
56
+ */
57
+ static VALUE
58
+ rlbug_query_summary_s_from_result( VALUE klass, VALUE query_result )
59
+ {
60
+ rlbug_query_result *result = rlbug_get_result( query_result );
61
+
62
+ lbug_query_summary *query_summary = ALLOC( lbug_query_summary );
63
+ VALUE query_summary_obj = rb_class_new_instance( 0, 0, klass );
64
+
65
+ /*
66
+ TODO Release the GIL
67
+ */
68
+ if ( lbug_query_result_get_query_summary(&result->result, query_summary) != LbugSuccess ) {
69
+ xfree( query_summary );
70
+ query_summary = NULL;
71
+ rb_raise( rlbug_eQueryError, "Could not fetch the query summary." );
72
+ }
73
+
74
+ DEBUG_GC( ">>> allocated query summary %p\n", query_summary );
75
+ RTYPEDDATA_DATA( query_summary_obj ) = query_summary;
76
+
77
+ return query_summary_obj;
78
+ }
79
+
80
+
81
+ /**
82
+ * call-seq:
83
+ * summary.compiling_time -> float
84
+ *
85
+ * Returns the compilation time of the given query summary in milliseconds.
86
+ *
87
+ */
88
+ static VALUE
89
+ rlbug_query_summary_compiling_time( VALUE self )
90
+ {
91
+ lbug_query_summary *summary = CHECK_QUERY_SUMMARY( self );
92
+ double result = lbug_query_summary_get_compiling_time( summary );
93
+
94
+ return rb_float_new( result );
95
+ }
96
+
97
+
98
+ /**
99
+ * call-seq:
100
+ * summary.execution_time -> float
101
+ *
102
+ * Returns the execution time of the given query summary in milliseconds.
103
+ *
104
+ */
105
+ static VALUE
106
+ rlbug_query_summary_execution_time( VALUE self )
107
+ {
108
+ lbug_query_summary *summary = CHECK_QUERY_SUMMARY( self );
109
+ double result = lbug_query_summary_get_execution_time( summary );
110
+
111
+ return rb_float_new( result );
112
+ }
113
+
114
+
115
+ /*
116
+ * Document-class: Ladybug::QuerySummary
117
+ */
118
+ void
119
+ rlbug_init_query_summary( void )
120
+ {
121
+ #ifdef FOR_RDOC
122
+ rlbug_mLadybug = rb_define_module( "ladybug" );
123
+ #endif
124
+
125
+ rlbug_cLadybugQuerySummary = rb_define_class_under( rlbug_mLadybug, "QuerySummary", rb_cObject );
126
+
127
+ rb_define_alloc_func( rlbug_cLadybugQuerySummary, rlbug_query_summary_s_allocate );
128
+ rb_undef_method( CLASS_OF(rlbug_cLadybugQuerySummary), "new" );
129
+
130
+ rb_define_singleton_method( rlbug_cLadybugQuerySummary, "from_result",
131
+ rlbug_query_summary_s_from_result, 1 );
132
+ rb_define_alias( CLASS_OF(rlbug_cLadybugQuerySummary), "from_query_result", "from_result" );
133
+
134
+ rb_define_method( rlbug_cLadybugQuerySummary, "compiling_time",
135
+ rlbug_query_summary_compiling_time, 0 );
136
+ rb_define_method( rlbug_cLadybugQuerySummary, "execution_time",
137
+ rlbug_query_summary_execution_time, 0 );
138
+
139
+ rb_require( "ladybug/query_summary" );
140
+ }
@@ -0,0 +1,24 @@
1
+ /*
2
+ * recursive_rel.c - Ladybug::RecursiveRel class
3
+ *
4
+ */
5
+
6
+ #include "ladybug_ext.h"
7
+
8
+ VALUE rlbug_cLadybugRecursiveRel;
9
+
10
+
11
+ /*
12
+ * Document-class: Ladybug::RecursiveRel
13
+ */
14
+ void
15
+ rlbug_init_recursive_rel( void )
16
+ {
17
+ #ifdef FOR_RDOC
18
+ rlbug_mLadybug = rb_define_module( "ladybug" );
19
+ #endif
20
+
21
+ rlbug_cLadybugRecursiveRel = rb_define_class_under( rlbug_mLadybug, "RecursiveRel", rb_cObject );
22
+
23
+ rb_require( "ladybug/recursive_rel" );
24
+ }