intersys 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +0 -0
- data/lib/common.c +61 -0
- data/lib/database.c +90 -0
- data/lib/definition.c +575 -0
- data/lib/extconf.rb +20 -0
- data/lib/intersys.c +83 -0
- data/lib/intersys.h +154 -0
- data/lib/intersys.rb +419 -0
- data/lib/object.c +69 -0
- data/lib/query.c +153 -0
- data/test/object.rb +17 -0
- data/test/query.rb +12 -0
- data/test/reflection.rb +65 -0
- data/test/strings.rb +14 -0
- metadata +69 -0
data/README
ADDED
File without changes
|
data/lib/common.c
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#include "intersys.h"
|
2
|
+
|
3
|
+
VALUE string_to_wchar(VALUE self) {
|
4
|
+
wchar_t w_chars[LEN(self) + 1];
|
5
|
+
int size;
|
6
|
+
RUN(cbind_utf8_to_uni(STR(self), (byte_size_t)LEN(self), w_chars, (char_size_t)sizeof(w_chars), &size));
|
7
|
+
w_chars[size] = 0;
|
8
|
+
return rb_str_new((char *)w_chars, (size+1)*sizeof(wchar_t));
|
9
|
+
}
|
10
|
+
|
11
|
+
VALUE string_from_wchar(VALUE self) {
|
12
|
+
char chars[LEN(self) + 1];
|
13
|
+
bzero(chars, sizeof(chars));
|
14
|
+
int size;
|
15
|
+
if(LEN(self) == 0 || !STR(self)) {
|
16
|
+
return rb_str_new2("");
|
17
|
+
}
|
18
|
+
RUN(cbind_uni_to_utf8(WCHARSTR(self), wcslen(WCHARSTR(self)), chars, sizeof(chars), &size));
|
19
|
+
return rb_str_new(chars, size);
|
20
|
+
}
|
21
|
+
|
22
|
+
|
23
|
+
int run(int err, char *file, int line) {
|
24
|
+
if (err != 0) {
|
25
|
+
VALUE handled = rb_funcall(mIntersys, rb_intern("handle_error"), 4,
|
26
|
+
INT2FIX(err), rb_str_new2(cbind_get_last_err_msg()), rb_str_new2(file), INT2FIX(line));
|
27
|
+
if(handled == Qnil) {
|
28
|
+
rb_raise(rb_eStandardError, "Intersystems Cache error %d: %s in file %s: %d", err, cbind_get_last_err_msg(), file, line);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
return err;
|
32
|
+
}
|
33
|
+
|
34
|
+
VALUE wcstr_new(const wchar_t *w_str, const char_size_t len) {
|
35
|
+
VALUE result;
|
36
|
+
int size, capa;
|
37
|
+
if(!w_str) {
|
38
|
+
return rb_funcall(rb_str_new2(""), rb_intern("to_wchar"), 0);
|
39
|
+
}
|
40
|
+
size = (int)(len)*sizeof(wchar_t);
|
41
|
+
capa = (int)(len + 1)*sizeof(wchar_t);
|
42
|
+
|
43
|
+
result = rb_str_new(0, 0);
|
44
|
+
|
45
|
+
RSTRING(result)->len = size;
|
46
|
+
RSTRING(result)->aux.capa = capa;
|
47
|
+
RSTRING(result)->ptr = ALLOC_N(char, capa);
|
48
|
+
bzero(RSTRING(result)->ptr, capa);
|
49
|
+
|
50
|
+
memcpy(RSTRING(result)->ptr, (char *)w_str, size);
|
51
|
+
rb_str_freeze(result);
|
52
|
+
return result;
|
53
|
+
}
|
54
|
+
|
55
|
+
VALUE rb_wcstr_new(const wchar_t *w_str, const char_size_t len) {
|
56
|
+
return wcstr_new(w_str, len);
|
57
|
+
}
|
58
|
+
|
59
|
+
VALUE rb_wcstr_new2(const wchar_t *w_str) {
|
60
|
+
return wcstr_new(w_str, w_str ? wcslen(w_str) : -1);
|
61
|
+
}
|
data/lib/database.c
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#include "intersys.h"
|
2
|
+
|
3
|
+
void intersys_base_free(struct rbDatabase* base) {
|
4
|
+
// printf("Releasing database\n");
|
5
|
+
RUN(cbind_free_db(base->database));
|
6
|
+
RUN(cbind_free_conn(base->connection));
|
7
|
+
free(base);
|
8
|
+
}
|
9
|
+
|
10
|
+
VALUE intersys_base_s_allocate(VALUE klass) {
|
11
|
+
struct rbDatabase* intersys_base = ALLOC(struct rbDatabase);
|
12
|
+
bzero(intersys_base, sizeof(struct rbDatabase));
|
13
|
+
return Data_Wrap_Struct(klass, 0, intersys_base_free, intersys_base);
|
14
|
+
}
|
15
|
+
|
16
|
+
VALUE intersys_base_initialize(VALUE self, VALUE options) {
|
17
|
+
return rb_funcall(self, rb_intern("connect"), 1, options);
|
18
|
+
}
|
19
|
+
|
20
|
+
static VALUE connect_get_options(VALUE options, char *opt_name, char *opt_default, int convert) {
|
21
|
+
VALUE res = rb_hash_aref(options, ID2SYM(rb_intern(opt_name)));
|
22
|
+
if(res == Qnil) {
|
23
|
+
res = rb_str_new2(opt_default);
|
24
|
+
}
|
25
|
+
if(convert) {
|
26
|
+
return rb_funcall(res, rb_intern("to_wchar"), 0);
|
27
|
+
}
|
28
|
+
return res;
|
29
|
+
}
|
30
|
+
|
31
|
+
VALUE intersys_base_connect(VALUE self, VALUE options) {
|
32
|
+
struct rbDatabase* base;
|
33
|
+
char conn_str[256];
|
34
|
+
wchar_t w_conn_str[256];
|
35
|
+
int size;
|
36
|
+
|
37
|
+
VALUE host, port, user, password, namespace, timeout;
|
38
|
+
|
39
|
+
host = connect_get_options(options, "host", "localhost", 0);
|
40
|
+
port = connect_get_options(options, "port", "1972", 0);
|
41
|
+
namespace = connect_get_options(options, "namespace", "Samples", 0);
|
42
|
+
|
43
|
+
user = connect_get_options(options, "user", "_SYSTEM", 1);
|
44
|
+
password = connect_get_options(options, "password", "SYS", 1);
|
45
|
+
timeout = rb_hash_aref(options, rb_intern("timeout"));
|
46
|
+
if (timeout == Qnil) {
|
47
|
+
timeout = INT2FIX(30);
|
48
|
+
}
|
49
|
+
|
50
|
+
Data_Get_Struct(self, struct rbDatabase, base);
|
51
|
+
|
52
|
+
snprintf(conn_str, sizeof(conn_str), "%s[%s]:%s", RSTRING(host)->ptr, RSTRING(port)->ptr, RSTRING(namespace)->ptr);
|
53
|
+
|
54
|
+
RUN(cbind_utf8_to_uni(conn_str, (byte_size_t)strlen(conn_str), w_conn_str, (char_size_t)sizeof(w_conn_str),&size));
|
55
|
+
w_conn_str[size] = 0;
|
56
|
+
|
57
|
+
RUN(cbind_alloc_conn(w_conn_str, WCHARSTR(user), WCHARSTR(password),
|
58
|
+
FIX2INT(timeout), &base->connection));
|
59
|
+
RUN(cbind_alloc_db(base->connection, &base->database));
|
60
|
+
return self;
|
61
|
+
}
|
62
|
+
|
63
|
+
VALUE intersys_base_start(VALUE self) {
|
64
|
+
struct rbDatabase* base;
|
65
|
+
Data_Get_Struct(self, struct rbDatabase, base);
|
66
|
+
RUN(cbind_tstart(base->database));
|
67
|
+
return Qtrue;
|
68
|
+
}
|
69
|
+
|
70
|
+
VALUE intersys_base_commit(VALUE self) {
|
71
|
+
struct rbDatabase* base;
|
72
|
+
Data_Get_Struct(self, struct rbDatabase, base);
|
73
|
+
RUN(cbind_tcommit(base->database));
|
74
|
+
return Qtrue;
|
75
|
+
}
|
76
|
+
|
77
|
+
VALUE intersys_base_rollback(VALUE self) {
|
78
|
+
struct rbDatabase* base;
|
79
|
+
Data_Get_Struct(self, struct rbDatabase, base);
|
80
|
+
RUN(cbind_trollback(base->database));
|
81
|
+
return Qtrue;
|
82
|
+
}
|
83
|
+
|
84
|
+
VALUE intersys_base_level(VALUE self) {
|
85
|
+
struct rbDatabase* base;
|
86
|
+
int level;
|
87
|
+
Data_Get_Struct(self, struct rbDatabase, base);
|
88
|
+
RUN(cbind_tlevel(base->database, &level));
|
89
|
+
return INT2FIX(level);
|
90
|
+
}
|
data/lib/definition.c
ADDED
@@ -0,0 +1,575 @@
|
|
1
|
+
#include "intersys.h"
|
2
|
+
|
3
|
+
static void intersys_definition_free(struct rbDefinition* definition) {
|
4
|
+
// printf("Releasing definition (%d)\n", definition->type);
|
5
|
+
switch(definition->type) {
|
6
|
+
case D_PROPERTY: {
|
7
|
+
RUN(cbind_free_prop_def(definition->def));
|
8
|
+
break;
|
9
|
+
}
|
10
|
+
case D_METHOD: {
|
11
|
+
RUN(cbind_free_mtd_def(definition->def));
|
12
|
+
break;
|
13
|
+
}
|
14
|
+
case D_ARGUMENT: {
|
15
|
+
RUN(cbind_free_arg_def(definition->def));
|
16
|
+
break;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
RUN(cbind_free_class_def(definition->database, definition->cl_def));
|
20
|
+
free(definition);
|
21
|
+
}
|
22
|
+
|
23
|
+
static void intersys_definition_mark(struct rbDefinition* definition) {
|
24
|
+
rb_gc_mark(definition->class_name);
|
25
|
+
}
|
26
|
+
|
27
|
+
VALUE intersys_definition_s_allocate(VALUE klass) {
|
28
|
+
struct rbDefinition* definition = ALLOC(struct rbDefinition);
|
29
|
+
bzero(definition, sizeof(struct rbDefinition));
|
30
|
+
return Data_Wrap_Struct(klass, intersys_definition_mark, intersys_definition_free, definition);
|
31
|
+
}
|
32
|
+
|
33
|
+
VALUE intersys_definition_initialize(VALUE self, VALUE r_database, VALUE class_name, VALUE name) {
|
34
|
+
struct rbDatabase* database;
|
35
|
+
struct rbDefinition* definition;
|
36
|
+
|
37
|
+
Data_Get_Struct(r_database, struct rbDatabase, database);
|
38
|
+
Data_Get_Struct(self, struct rbDefinition, definition);
|
39
|
+
|
40
|
+
definition->database = database->database;
|
41
|
+
definition->in_name = WCHARSTR(name);
|
42
|
+
definition->class_name = TOWCHAR(class_name);
|
43
|
+
|
44
|
+
RUN(cbind_alloc_class_def(definition->database, CLASS_NAME(definition), &definition->cl_def));
|
45
|
+
return self;
|
46
|
+
}
|
47
|
+
|
48
|
+
VALUE intersys_definition_cpp_type(VALUE self) {
|
49
|
+
struct rbDefinition* definition;
|
50
|
+
Data_Get_Struct(self, struct rbDefinition, definition);
|
51
|
+
return INT2FIX(definition->cpp_type);
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
VALUE intersys_definition_cache_type(VALUE self) {
|
56
|
+
struct rbDefinition* definition;
|
57
|
+
Data_Get_Struct(self, struct rbDefinition, definition);
|
58
|
+
return FROMWCSTR(definition->cache_type);
|
59
|
+
}
|
60
|
+
|
61
|
+
VALUE intersys_definition_name(VALUE self) {
|
62
|
+
struct rbDefinition* definition;
|
63
|
+
Data_Get_Struct(self, struct rbDefinition, definition);
|
64
|
+
return FROMWCSTR(definition->name);
|
65
|
+
}
|
66
|
+
|
67
|
+
VALUE intersys_definition_in_name(VALUE self) {
|
68
|
+
struct rbDefinition* definition;
|
69
|
+
Data_Get_Struct(self, struct rbDefinition, definition);
|
70
|
+
return FROMWCSTR(definition->in_name);
|
71
|
+
}
|
72
|
+
|
73
|
+
VALUE intersys_property_initialize(VALUE self, VALUE r_database, VALUE class_name, VALUE name, VALUE object) {
|
74
|
+
struct rbDefinition* property;
|
75
|
+
struct rbObject* obj;
|
76
|
+
VALUE args[] = {r_database, class_name, name};
|
77
|
+
rb_call_super(3, args);
|
78
|
+
|
79
|
+
Data_Get_Struct(self, struct rbDefinition, property);
|
80
|
+
Data_Get_Struct(object, struct rbObject, obj);
|
81
|
+
|
82
|
+
property->type = D_PROPERTY;
|
83
|
+
RUN(cbind_alloc_prop_def(&property->def));
|
84
|
+
RUN(cbind_get_prop_def(property->cl_def, property->in_name, property->def));
|
85
|
+
RUN(cbind_get_prop_cpp_type(property->def, &property->cpp_type));
|
86
|
+
RUN(cbind_get_prop_cache_type(property->def, &property->cache_type));
|
87
|
+
RUN(cbind_get_prop_name(property->def, &property->name));
|
88
|
+
property->oref = obj->oref;
|
89
|
+
return self;
|
90
|
+
}
|
91
|
+
|
92
|
+
|
93
|
+
VALUE intersys_property_get(VALUE self) {
|
94
|
+
struct rbDefinition* property;
|
95
|
+
|
96
|
+
Data_Get_Struct(self, struct rbDefinition, property);
|
97
|
+
|
98
|
+
RUN(cbind_reset_args(property->database));
|
99
|
+
RUN(cbind_set_next_arg_as_res(property->database, property->cpp_type));
|
100
|
+
RUN(cbind_get_prop(property->database, property->oref, property->in_name));
|
101
|
+
return rb_funcall(self, rb_intern("extract_retval!"), 0);
|
102
|
+
}
|
103
|
+
|
104
|
+
VALUE intersys_property_set(VALUE self, VALUE value) {
|
105
|
+
struct rbDefinition* property;
|
106
|
+
|
107
|
+
Data_Get_Struct(self, struct rbDefinition, property);
|
108
|
+
|
109
|
+
RUN(cbind_reset_args(property->database));
|
110
|
+
rb_funcall(self, rb_intern("marshall!"), 1, value);
|
111
|
+
RUN(cbind_set_prop(property->database, property->oref, property->in_name));
|
112
|
+
return self;
|
113
|
+
}
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
VALUE intersys_method_initialize(VALUE self, VALUE object) {
|
118
|
+
struct rbDefinition* method;
|
119
|
+
|
120
|
+
Data_Get_Struct(self, struct rbDefinition, method);
|
121
|
+
|
122
|
+
method->type = D_METHOD;
|
123
|
+
RUN(cbind_alloc_mtd_def(&method->def));
|
124
|
+
RUN(cbind_get_mtd_def(method->cl_def, method->in_name, method->def));
|
125
|
+
RUN(cbind_get_mtd_is_func(method->def, &method->is_func));
|
126
|
+
RUN(cbind_get_mtd_cpp_type(method->def, &method->cpp_type));
|
127
|
+
RUN(cbind_get_mtd_cache_type(method->def, &method->cache_type));
|
128
|
+
RUN(cbind_get_mtd_is_cls_mtd(method->def, &method->is_class_method));
|
129
|
+
RUN(cbind_get_mtd_num_args(method->def, &method->num_args));
|
130
|
+
RUN(cbind_get_mtd_args_info(method->def, &method->args_info));
|
131
|
+
RUN(cbind_get_mtd_name(method->def, &method->name));
|
132
|
+
if(object != Qnil) {
|
133
|
+
struct rbObject* obj;
|
134
|
+
Data_Get_Struct(object, struct rbObject, obj);
|
135
|
+
method->oref = obj->oref;
|
136
|
+
rb_iv_set(self, "@object", object);
|
137
|
+
} else {
|
138
|
+
method->oref = -1;
|
139
|
+
}
|
140
|
+
return self;
|
141
|
+
}
|
142
|
+
|
143
|
+
VALUE intersys_method_is_func(VALUE self) {
|
144
|
+
struct rbDefinition* method;
|
145
|
+
Data_Get_Struct(self, struct rbDefinition, method);
|
146
|
+
return method->is_func ? Qtrue : Qfalse;
|
147
|
+
}
|
148
|
+
|
149
|
+
|
150
|
+
VALUE intersys_method_is_class_method(VALUE self) {
|
151
|
+
struct rbDefinition* method;
|
152
|
+
Data_Get_Struct(self, struct rbDefinition, method);
|
153
|
+
return method->is_class_method ? Qtrue : Qfalse;
|
154
|
+
}
|
155
|
+
|
156
|
+
VALUE intersys_method_num_args(VALUE self) {
|
157
|
+
struct rbDefinition* method;
|
158
|
+
Data_Get_Struct(self, struct rbDefinition, method);
|
159
|
+
return INT2FIX(method->num_args);
|
160
|
+
}
|
161
|
+
|
162
|
+
VALUE intersys_method_prepare_call(VALUE self) {
|
163
|
+
struct rbDefinition* method;
|
164
|
+
|
165
|
+
Data_Get_Struct(self, struct rbDefinition, method);
|
166
|
+
|
167
|
+
RUN(cbind_reset_args(method->database));
|
168
|
+
RUN(cbind_mtd_rewind_args(method->def));
|
169
|
+
return self;
|
170
|
+
}
|
171
|
+
|
172
|
+
VALUE intersys_method_call(VALUE self) {
|
173
|
+
struct rbDefinition* method;
|
174
|
+
|
175
|
+
Data_Get_Struct(self, struct rbDefinition, method);
|
176
|
+
|
177
|
+
if (method->cpp_type != CBIND_VOID) {
|
178
|
+
RUN(cbind_set_next_arg_as_res(method->database, method->cpp_type));
|
179
|
+
}
|
180
|
+
RUN(cbind_run_method(method->database, method->oref, CLASS_NAME(method), method->in_name));
|
181
|
+
return self;
|
182
|
+
}
|
183
|
+
|
184
|
+
static VALUE extract_next_dlist_elem(char *dlist, int* elem_size) {
|
185
|
+
bool_t flag;
|
186
|
+
|
187
|
+
RUN(cbind_dlist_is_elem_null(dlist,&flag));
|
188
|
+
if (flag) {
|
189
|
+
RUN(cbind_dlist_get_elem_size(dlist, elem_size));
|
190
|
+
return Qnil;
|
191
|
+
}
|
192
|
+
|
193
|
+
RUN(cbind_dlist_is_elem_int(dlist,&flag));
|
194
|
+
if (flag) { // process integer
|
195
|
+
int val;
|
196
|
+
RUN(cbind_dlist_get_elem_as_int(dlist, &val, elem_size));
|
197
|
+
return NUM2INT(val);
|
198
|
+
}
|
199
|
+
RUN(cbind_dlist_is_elem_double(dlist,&flag));
|
200
|
+
if (flag) { // process double
|
201
|
+
double val;
|
202
|
+
RUN(cbind_dlist_get_elem_as_double(dlist, &val, elem_size));
|
203
|
+
return rb_float_new(val);
|
204
|
+
}
|
205
|
+
RUN(cbind_dlist_is_elem_str(dlist,&flag));
|
206
|
+
if (flag) { // process string
|
207
|
+
const char *str;
|
208
|
+
int size;
|
209
|
+
bool_t is_uni;
|
210
|
+
VALUE val;
|
211
|
+
|
212
|
+
RUN(cbind_dlist_get_str_elem(dlist, &is_uni, &str, &size, elem_size));
|
213
|
+
val = rb_str_new(str, size);
|
214
|
+
if (is_uni) {
|
215
|
+
val = FROMWCHAR(val);
|
216
|
+
}
|
217
|
+
return val;
|
218
|
+
}
|
219
|
+
rb_raise(cUnMarshallError, "Couldn't unmarshall dlist element");
|
220
|
+
}
|
221
|
+
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
VALUE intersys_method_extract_retval(VALUE self) {
|
226
|
+
struct rbDefinition* method;
|
227
|
+
bool_t is_null;
|
228
|
+
|
229
|
+
Data_Get_Struct(self, struct rbDefinition, method);
|
230
|
+
if(method->cpp_type == CBIND_VOID) {
|
231
|
+
return Qnil;
|
232
|
+
}
|
233
|
+
|
234
|
+
|
235
|
+
RUN(cbind_get_is_null(method->database, method->num_args, &is_null));
|
236
|
+
if(is_null) {
|
237
|
+
return Qnil;
|
238
|
+
}
|
239
|
+
|
240
|
+
switch(method->cpp_type) {
|
241
|
+
case CBIND_VOID: {
|
242
|
+
return Qnil;
|
243
|
+
}
|
244
|
+
|
245
|
+
case CBIND_OBJ_ID: {
|
246
|
+
int oref = 0;
|
247
|
+
char_size_t len = 0;
|
248
|
+
bool_t is_null = 1;
|
249
|
+
VALUE result = Qnil, klass;
|
250
|
+
VALUE class_name_w, class_name;
|
251
|
+
const wchar_t *cl_name = 0;
|
252
|
+
struct rbObject* object;
|
253
|
+
RUN(cbind_get_arg_as_obj(method->database, method->num_args, &oref, &cl_name, &len, &is_null));
|
254
|
+
if(is_null) {
|
255
|
+
printf("Loaded NULL object\n");
|
256
|
+
return Qnil;
|
257
|
+
}
|
258
|
+
class_name_w = rb_wcstr_new(cl_name, len);
|
259
|
+
class_name = FROMWCHAR(class_name_w);
|
260
|
+
klass = rb_funcall(cObject, rb_intern("lookup"), 1, class_name);
|
261
|
+
result = rb_funcall(klass, rb_intern("new"), 0);
|
262
|
+
Data_Get_Struct(result, struct rbObject, object);
|
263
|
+
object->oref = oref;
|
264
|
+
return result;
|
265
|
+
}
|
266
|
+
|
267
|
+
case CBIND_TIME_ID:
|
268
|
+
{
|
269
|
+
int hour, minute, second;
|
270
|
+
RUN(cbind_get_arg_as_time(method->database, method->num_args, &hour, &minute, &second, &is_null));
|
271
|
+
return Qnil;
|
272
|
+
break;
|
273
|
+
}
|
274
|
+
case CBIND_DATE_ID:
|
275
|
+
{
|
276
|
+
int year, month,day;
|
277
|
+
RUN(cbind_get_arg_as_date(method->database, method->num_args, &year, &month, &day, &is_null));
|
278
|
+
return Qnil;
|
279
|
+
break;
|
280
|
+
}
|
281
|
+
case CBIND_TIMESTAMP_ID:
|
282
|
+
{
|
283
|
+
int year, month, day, hour, minute, second, fraction;
|
284
|
+
RUN(cbind_get_arg_as_timestamp(method->database, method->num_args,
|
285
|
+
&year, &month, &day, &hour, &minute, &second, &fraction, &is_null));
|
286
|
+
return Qnil;
|
287
|
+
break;
|
288
|
+
}
|
289
|
+
|
290
|
+
case CBIND_INT_ID: {
|
291
|
+
int val;
|
292
|
+
RUN(cbind_get_arg_as_int(method->database, method->num_args, &val, &is_null));
|
293
|
+
return INT2FIX(val);
|
294
|
+
}
|
295
|
+
|
296
|
+
case CBIND_DOUBLE_ID: {
|
297
|
+
double val;
|
298
|
+
RUN(cbind_get_arg_as_double(method->database, method->num_args, &val, &is_null));
|
299
|
+
return rb_float_new(val);
|
300
|
+
}
|
301
|
+
case CBIND_CURRENCY_ID:
|
302
|
+
{
|
303
|
+
double val;
|
304
|
+
RUN(cbind_get_arg_as_cy(method->database, method->num_args, &val, &is_null));
|
305
|
+
return rb_float_new(val);
|
306
|
+
}
|
307
|
+
|
308
|
+
case CBIND_BINARY_ID: {
|
309
|
+
byte_size_t size;
|
310
|
+
char *buf;
|
311
|
+
VALUE result = rb_str_new(0, 0);
|
312
|
+
|
313
|
+
RUN(cbind_get_arg_as_bin(method->database, method->num_args, NULL, 0, &size, &is_null));
|
314
|
+
buf = ALLOC_N(char, size + 1);
|
315
|
+
RUN(cbind_get_arg_as_bin(method->database, method->num_args, buf, size, &size, &is_null));
|
316
|
+
|
317
|
+
RSTRING(result)->ptr = buf;
|
318
|
+
RSTRING(result)->len = size;
|
319
|
+
RSTRING(result)->aux.capa = size;
|
320
|
+
return result;
|
321
|
+
}
|
322
|
+
case CBIND_STATUS_ID:{
|
323
|
+
byte_size_t size;
|
324
|
+
char *buf;
|
325
|
+
int code;
|
326
|
+
|
327
|
+
RUN(cbind_get_arg_as_status(method->database, method->num_args, &code, NULL, 0, MULTIBYTE, &size, &is_null));
|
328
|
+
buf = ALLOC_N(char, size + 1);
|
329
|
+
RUN(cbind_get_arg_as_status(method->database, method->num_args, &code, buf, size, MULTIBYTE, &size, &is_null));
|
330
|
+
|
331
|
+
free(buf);
|
332
|
+
return rb_funcall(cStatus, rb_intern("new"), 2, INT2NUM(code), FROMWCHAR(rb_str_new(buf, size)));
|
333
|
+
}
|
334
|
+
|
335
|
+
case CBIND_STRING_ID: {
|
336
|
+
byte_size_t size;
|
337
|
+
char *buf;
|
338
|
+
VALUE result = rb_str_new(0, 0);
|
339
|
+
VALUE res;
|
340
|
+
|
341
|
+
RUN(cbind_get_arg_as_str(method->database, method->num_args, NULL, 0, CPP_UNICODE, &size, &is_null));
|
342
|
+
//It is important to add wchar_t to end, because for wcslen we need more than 1 terminating zero.
|
343
|
+
//I don't know exactly, how works wcslen, but I add 4 (sizeof wchar_t) terminating zeroes
|
344
|
+
buf = ALLOC_N(char, size + sizeof(wchar_t));
|
345
|
+
bzero(buf, size + sizeof(wchar_t));
|
346
|
+
RUN(cbind_get_arg_as_str(method->database, method->num_args, buf, size, CPP_UNICODE, &size, &is_null));
|
347
|
+
|
348
|
+
RSTRING(result)->ptr = buf;
|
349
|
+
RSTRING(result)->len = size;
|
350
|
+
RSTRING(result)->aux.capa = size;
|
351
|
+
res = rb_funcall(result, rb_intern("from_wchar"), 0);
|
352
|
+
return res;
|
353
|
+
}
|
354
|
+
|
355
|
+
case CBIND_BOOL_ID:
|
356
|
+
{
|
357
|
+
bool_t val;
|
358
|
+
RUN(cbind_get_arg_as_bool(method->database, method->num_args, &val, &is_null));
|
359
|
+
if(val) {
|
360
|
+
return Qtrue;
|
361
|
+
}
|
362
|
+
return Qfalse;
|
363
|
+
}
|
364
|
+
|
365
|
+
case CBIND_DLIST_ID:
|
366
|
+
{
|
367
|
+
char *buf;
|
368
|
+
char *p;
|
369
|
+
byte_size_t size;
|
370
|
+
int num_elems;
|
371
|
+
int i;
|
372
|
+
VALUE list;
|
373
|
+
|
374
|
+
RUN(cbind_get_arg_as_dlist(method->database, method->num_args, NULL, 0, &size, &is_null));
|
375
|
+
buf = ALLOC_N(char, size);
|
376
|
+
RUN(cbind_get_arg_as_dlist(method->database, method->num_args, buf, size, &size, &is_null));
|
377
|
+
|
378
|
+
RUN(cbind_dlist_calc_num_elems(buf, size, &num_elems));
|
379
|
+
list = rb_ary_new2(num_elems);
|
380
|
+
p = buf;
|
381
|
+
for (i=0; i < num_elems; i++) {
|
382
|
+
int elem_size;
|
383
|
+
rb_ary_push(list, extract_next_dlist_elem(p, &elem_size));
|
384
|
+
p += elem_size;
|
385
|
+
}
|
386
|
+
free(buf);
|
387
|
+
return list;
|
388
|
+
}
|
389
|
+
|
390
|
+
}
|
391
|
+
return Qnil;
|
392
|
+
}
|
393
|
+
|
394
|
+
|
395
|
+
VALUE intersys_argument_initialize(VALUE self, VALUE r_database, VALUE class_name, VALUE name, VALUE r_method) {
|
396
|
+
struct rbDefinition* argument;
|
397
|
+
struct rbDefinition* method;
|
398
|
+
VALUE args[] = {r_database, class_name, name};
|
399
|
+
rb_call_super(3, args);
|
400
|
+
|
401
|
+
Data_Get_Struct(self, struct rbDefinition, argument);
|
402
|
+
Data_Get_Struct(r_method, struct rbDefinition, method);
|
403
|
+
|
404
|
+
|
405
|
+
argument->type = D_ARGUMENT;
|
406
|
+
RUN(cbind_alloc_arg_def(&argument->def));
|
407
|
+
RUN(cbind_mtd_arg_get(method->def, argument->def));
|
408
|
+
RUN(cbind_get_arg_cpp_type(argument->def, &argument->cpp_type));
|
409
|
+
RUN(cbind_get_arg_cache_type(argument->def, &argument->cache_type));
|
410
|
+
RUN(cbind_get_arg_name(argument->def, &argument->name));
|
411
|
+
RUN(cbind_get_arg_is_by_ref(argument->def, &argument->is_by_ref));
|
412
|
+
RUN(cbind_get_arg_is_default(argument->def, &argument->is_default));
|
413
|
+
RUN(cbind_get_arg_def_val(argument->def, &argument->default_value));
|
414
|
+
RUN(cbind_get_arg_def_val_size(argument->def, &argument->default_value_size));
|
415
|
+
RUN(cbind_mtd_arg_next(method->def));
|
416
|
+
argument->arg_number = method->arg_counter;
|
417
|
+
method->arg_counter++;
|
418
|
+
return self;
|
419
|
+
}
|
420
|
+
|
421
|
+
VALUE intersys_argument_default_value(VALUE self) {
|
422
|
+
struct rbDefinition* argument;
|
423
|
+
Data_Get_Struct(self, struct rbDefinition, argument);
|
424
|
+
if(!argument->is_default) {
|
425
|
+
return Qnil;
|
426
|
+
}
|
427
|
+
return rb_str_new(argument->default_value, argument->default_value_size);
|
428
|
+
}
|
429
|
+
|
430
|
+
VALUE intersys_argument_marshall_dlist_elem(VALUE self, VALUE elem) {
|
431
|
+
struct rbDefinition* argument;
|
432
|
+
Data_Get_Struct(self, struct rbDefinition, argument);
|
433
|
+
int elem_size;
|
434
|
+
|
435
|
+
switch(TYPE(elem)) {
|
436
|
+
case T_NIL: {
|
437
|
+
RUN(cbind_dlist_put_null_elem(argument->current_dlist, argument->current_dlist_size, &elem_size));
|
438
|
+
break;
|
439
|
+
}
|
440
|
+
case T_FIXNUM: {
|
441
|
+
RUN(cbind_dlist_put_int_elem(argument->current_dlist, argument->current_dlist_size, FIX2INT(elem), &elem_size));
|
442
|
+
break;
|
443
|
+
}
|
444
|
+
case T_FLOAT: {
|
445
|
+
RUN(cbind_dlist_put_double_elem(argument->current_dlist, argument->current_dlist_size, RFLOAT(elem)->value, &elem_size));
|
446
|
+
break;
|
447
|
+
}
|
448
|
+
case T_STRING: {
|
449
|
+
VALUE val = TOWCHAR(elem);
|
450
|
+
RUN(cbind_dlist_put_str_elem(argument->current_dlist, argument->current_dlist_size, 1, STR(val), LEN(val), &elem_size));
|
451
|
+
break;
|
452
|
+
}
|
453
|
+
default: {
|
454
|
+
rb_raise(cMarshallError, "couldn't marshall to dlist element: %s", STR(CALL(elem, "inspect")));
|
455
|
+
return Qnil;
|
456
|
+
}
|
457
|
+
}
|
458
|
+
argument->current_dlist_size -= elem_size;
|
459
|
+
argument->current_dlist += elem_size;
|
460
|
+
return elem;
|
461
|
+
}
|
462
|
+
|
463
|
+
|
464
|
+
VALUE intersys_argument_set(VALUE self, VALUE obj) {
|
465
|
+
struct rbDefinition* property;
|
466
|
+
Data_Get_Struct(self, struct rbDefinition, property);
|
467
|
+
|
468
|
+
if(obj == Qnil) {
|
469
|
+
RUN(cbind_set_next_arg_as_null(property->database, property->cpp_type, property->is_by_ref));
|
470
|
+
return obj;
|
471
|
+
}
|
472
|
+
switch (property->cpp_type) {
|
473
|
+
case CBIND_VOID:
|
474
|
+
break;
|
475
|
+
case CBIND_OBJ_ID:
|
476
|
+
{
|
477
|
+
struct rbObject* param;
|
478
|
+
Data_Get_Struct(obj, struct rbObject, param);
|
479
|
+
RUN(cbind_set_next_arg_as_obj(property->database, param->oref, WCHARSTR(param->class_name), property->is_by_ref));
|
480
|
+
break;
|
481
|
+
}
|
482
|
+
case CBIND_INT_ID:
|
483
|
+
{
|
484
|
+
VALUE i = rb_funcall(obj, rb_intern("to_i"), 0);
|
485
|
+
RUN(cbind_set_next_arg_as_int(property->database, NUM2INT(i), property->is_by_ref));
|
486
|
+
break;
|
487
|
+
}
|
488
|
+
case CBIND_DOUBLE_ID:
|
489
|
+
{
|
490
|
+
VALUE f = rb_funcall(obj, rb_intern("to_f"), 0);
|
491
|
+
RUN(cbind_set_next_arg_as_double(property->database, RFLOAT(f)->value, property->is_by_ref));
|
492
|
+
break;
|
493
|
+
}
|
494
|
+
case CBIND_BINARY_ID:
|
495
|
+
{
|
496
|
+
VALUE res = Qnil;
|
497
|
+
if(rb_respond_to(obj, rb_intern("to_s"))) {
|
498
|
+
res = rb_funcall(obj, rb_intern("to_s"), 0);
|
499
|
+
} else if (rb_respond_to(obj, rb_intern("read"))) {
|
500
|
+
res = rb_funcall(obj, rb_intern("read"), 0);
|
501
|
+
} else {
|
502
|
+
rb_raise(rb_eStandardError, "Cannot marshall object");
|
503
|
+
break;
|
504
|
+
}
|
505
|
+
RUN(cbind_set_next_arg_as_bin(property->database, STR(res), LEN(res), property->is_by_ref));
|
506
|
+
break;
|
507
|
+
}
|
508
|
+
case CBIND_STRING_ID:
|
509
|
+
{
|
510
|
+
VALUE res = (rb_funcall(obj, rb_intern("to_s"), 0));
|
511
|
+
RUN(cbind_set_next_arg_as_str(property->database, STR(res), LEN(res), MULTIBYTE, property->is_by_ref));
|
512
|
+
break;
|
513
|
+
}
|
514
|
+
case CBIND_STATUS_ID:
|
515
|
+
{
|
516
|
+
// TBD
|
517
|
+
break;
|
518
|
+
}
|
519
|
+
case CBIND_TIME_ID:
|
520
|
+
{
|
521
|
+
int hour = NUM2INT(CALL(obj, "hour"));
|
522
|
+
int minute = NUM2INT(CALL(obj, "min"));
|
523
|
+
int second = NUM2INT(CALL(obj, "sec"));
|
524
|
+
RUN(cbind_set_next_arg_as_time(property->database, hour, minute, second, property->is_by_ref));
|
525
|
+
break;
|
526
|
+
}
|
527
|
+
case CBIND_DATE_ID:
|
528
|
+
{
|
529
|
+
int year = NUM2INT(CALL(obj, "year"));
|
530
|
+
int month = NUM2INT(CALL(obj, "month"));
|
531
|
+
int day = NUM2INT(CALL(obj, "day"));
|
532
|
+
RUN(cbind_set_next_arg_as_date(property->database, year, month, day, property->is_by_ref));
|
533
|
+
break;
|
534
|
+
}
|
535
|
+
case CBIND_TIMESTAMP_ID:
|
536
|
+
{
|
537
|
+
int year = NUM2INT(CALL(obj, "year"));
|
538
|
+
int month = NUM2INT(CALL(obj, "month"));
|
539
|
+
int day = NUM2INT(CALL(obj, "day"));
|
540
|
+
int hour = NUM2INT(CALL(obj, "hour"));
|
541
|
+
int minute = NUM2INT(CALL(obj, "min"));
|
542
|
+
int second = NUM2INT(CALL(obj, "sec"));
|
543
|
+
int fraction = 0;
|
544
|
+
RUN(cbind_set_next_arg_as_timestamp(property->database,
|
545
|
+
year, month, day, hour, minute, second, fraction, property->is_by_ref));
|
546
|
+
break;
|
547
|
+
}
|
548
|
+
case CBIND_BOOL_ID:
|
549
|
+
{
|
550
|
+
bool_t res = RTEST(obj);
|
551
|
+
RUN(cbind_set_next_arg_as_bool(property->database, res, property->is_by_ref));
|
552
|
+
break;
|
553
|
+
}
|
554
|
+
case CBIND_DLIST_ID:
|
555
|
+
{
|
556
|
+
char buf[327];
|
557
|
+
|
558
|
+
property->current_dlist_size = sizeof(buf);
|
559
|
+
property->current_dlist = buf;
|
560
|
+
rb_funcall(self, rb_intern("marshall_dlist"), 1, obj);
|
561
|
+
RUN(cbind_set_next_arg_as_dlist(property->database, buf, sizeof(buf) - property->current_dlist_size, property->is_by_ref));
|
562
|
+
property->current_dlist_size = 0;
|
563
|
+
property->current_dlist = 0;
|
564
|
+
break;
|
565
|
+
|
566
|
+
}
|
567
|
+
|
568
|
+
default:
|
569
|
+
rb_raise(rb_eStandardError,"unknown type for argument, type = %d",
|
570
|
+
property->cpp_type, CLASS_NAME(property));
|
571
|
+
return Qnil;
|
572
|
+
}
|
573
|
+
return obj;
|
574
|
+
|
575
|
+
}
|