active_sql 1.0.1 → 2.0.1

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,354 @@
1
+ /*
2
+ Sasie
3
+ sasieindrajit@gmail.com
4
+ */
5
+
6
+ #define IfNILorSTRING(obj) (NIL_P(obj)? NULL: StringValuePtr(obj))
7
+ #define IfNILorINT(obj) (NIL_P(obj)? 0: NUM2INT(obj))
8
+
9
+ struct config {
10
+ char *ser, *user, *pass, *db, *sock;
11
+ unsigned int pp, flg;
12
+ };
13
+
14
+ struct mysql {
15
+ MYSQL *conn;
16
+ unsigned int reconnect;
17
+ unsigned int adds;
18
+ };
19
+
20
+ struct config myConfig;
21
+ struct mysql mysObj;
22
+
23
+ static VALUE activeSQL;
24
+ static VALUE rb_cBase;
25
+ static VALUE rb_eSqlError;
26
+ static VALUE rb_cCols;
27
+
28
+ void Init_activesql();
29
+
30
+ // Definition section.
31
+ static void init_active_sqls();
32
+ static VALUE activeSQL_load_config(int argc, VALUE *argv, VALUE self);
33
+ static VALUE activeSQL_version(VALUE self);
34
+ static VALUE activeSQL_connect(VALUE self);
35
+ static VALUE activeSQL_reconnect(VALUE self);
36
+ static VALUE activeSQL_disconnect(VALUE self);
37
+ static VALUE activeSQL_connected(VALUE self);
38
+ static VALUE activeSQL_exec(VALUE self, VALUE arg, VALUE ret_vl);
39
+ static VALUE activeSQL_set_chars_set(int argc, VALUE *argv, VALUE self);
40
+ static VALUE activeSQL_exec_sql(VALUE self, VALUE arg);
41
+ static int castPreWrk(enum enum_field_types typ);
42
+ static VALUE castFrFetch(unsigned int typ, VALUE row, unsigned int itr);
43
+ static VALUE activeSQL_dyamic_meth(VALUE self);
44
+ static VALUE activeSQL_add_methods(int argc, VALUE *argv, VALUE self);
45
+ static VALUE activeSQL_added_methods(VALUE self);
46
+ static VALUE activeSQL_my_database(int argc, VALUE *argv, VALUE self);
47
+ static VALUE activeSQL_my_select(VALUE self);
48
+ static VALUE activeSQL_auto_commit(VALUE self, VALUE arg);
49
+
50
+ // Def.
51
+ static VALUE activeSQL_auto_commit(VALUE self, VALUE arg) {
52
+ //if (mysql_autocommit(mysObj.conn, 1) == 0)
53
+ // return Qtrue; Do it from query.
54
+ }
55
+
56
+ static VALUE activeSQL_my_select(VALUE self) {
57
+ return rb_reg_new("\\A\\s*(SELECT|SHOW|DESCRIBE|EXPLAIN|CHECK TABLE|DESC|CALL)", 57, 1);
58
+ }
59
+
60
+ static VALUE activeSQL_my_database(int argc, VALUE *argv, VALUE self) {
61
+ VALUE cdb;
62
+ if (!mysObj.reconnect) {
63
+ rb_scan_args(argc, argv, "01", &cdb);
64
+ if (TYPE(cdb) == T_STRING)
65
+ if (mysql_select_db(mysObj.conn, RSTRING_PTR(cdb)) == 0)
66
+ return Qtrue;
67
+ else
68
+ return Qfalse;
69
+ else
70
+ return Qfalse;
71
+ }
72
+ else
73
+ rb_raise(rb_eSqlError, "Connection not established.");
74
+ }
75
+
76
+ static VALUE activeSQL_added_methods(VALUE self) {
77
+ if (mysObj.adds == 0)
78
+ return Qtrue;
79
+ else
80
+ return Qfalse;
81
+ }
82
+
83
+ static VALUE activeSQL_add_methods(int argc, VALUE *argv, VALUE self) {
84
+ VALUE needed;
85
+ rb_scan_args(argc, argv, "01", &needed);
86
+ if (TYPE(needed) == T_TRUE) {
87
+ mysObj.adds = 0;
88
+ return Qtrue;
89
+ }
90
+ else if (TYPE(needed) == T_FALSE) {
91
+ mysObj.adds = 1;
92
+ return Qtrue;
93
+ }
94
+ else
95
+ return Qfalse;
96
+ }
97
+
98
+ static VALUE activeSQL_dyamic_meth(VALUE self) {
99
+ //unsigned int ind = findIndex();
100
+ //return RARRAY(self)->ptr[ind];
101
+ }
102
+
103
+ static VALUE activeSQL_exec_sql(VALUE self, VALUE arg) {
104
+ VALUE f;
105
+ if (mysObj.reconnect == 1)
106
+ f = rb_funcall(rb_cBase, rb_intern("connect!"), 0);
107
+ else
108
+ f = Qtrue;
109
+ if (TYPE(f) == T_TRUE) {
110
+ if (TYPE(arg) != T_STRING)
111
+ rb_raise(rb_eTypeError, "invalid type for input");
112
+ if (mysql_real_query(mysObj.conn, RSTRING_PTR(arg), (unsigned int) strlen(RSTRING_PTR(arg))))
113
+ rb_raise(rb_eSqlError, mysql_error(mysObj.conn));
114
+ else
115
+ return Qtrue;
116
+ }
117
+ else
118
+ rb_raise(rb_eSqlError, "Connection not established.");
119
+ }
120
+
121
+ static VALUE activeSQL_set_chars_set(int argc, VALUE *argv, VALUE self) {
122
+ VALUE cset;
123
+ if (!mysObj.reconnect) {
124
+ rb_scan_args(argc, argv, "01", &cset);
125
+ if (TYPE(cset) == T_STRING)
126
+ if (!mysql_set_character_set(mysObj.conn, RSTRING_PTR(cset)))
127
+ return rb_str_new2(mysql_character_set_name(mysObj.conn));
128
+ else
129
+ return Qfalse;
130
+ else
131
+ return rb_str_new2(mysql_character_set_name(mysObj.conn));
132
+ }
133
+ else
134
+ rb_raise(rb_eSqlError, "Connection not established.");
135
+ }
136
+
137
+ static VALUE activeSQL_exec(VALUE self, VALUE arg, VALUE ret_vl) {
138
+ unsigned int * castAs;
139
+ unsigned int i, n, fld_cnt, j;
140
+ unsigned long * lengths;
141
+ char **getters;
142
+ char *tbl_name;
143
+ char *dyn_method;
144
+ MYSQL_RES *res;
145
+ MYSQL_ROW row;
146
+ MYSQL_FIELD *fields;
147
+ VALUE ary, f, cmd;
148
+ VALUE res_set; //Colllect result to send it back.
149
+ if (mysObj.reconnect == 1)
150
+ f = rb_funcall(rb_cBase, rb_intern("connect!"), 0);
151
+ else
152
+ f = Qtrue;
153
+ if (TYPE(f) == T_TRUE) {
154
+ if (TYPE(arg) != T_STRING)
155
+ rb_raise(rb_eTypeError, "invalid type for input");
156
+ if (mysql_real_query(mysObj.conn, RSTRING_PTR(arg), (unsigned int) strlen(RSTRING_PTR(arg)))) {
157
+ rb_raise(rb_eSqlError, mysql_error(mysObj.conn));
158
+ }
159
+ if (TYPE(ret_vl) == T_TRUE) {
160
+ res = mysql_use_result(mysObj.conn);
161
+ res_set = rb_ary_new();
162
+ fld_cnt = mysql_num_fields(res);
163
+ fields = mysql_fetch_fields(res);
164
+ ary = rb_ary_new2(fld_cnt);
165
+
166
+ /* ALLOCATE ROOM : DYN METHODS FOR GETTERS */
167
+ getters = (char **) malloc(fld_cnt * sizeof (char *));
168
+ castAs = (unsigned int*) malloc(fld_cnt * sizeof (int));
169
+
170
+ for (i = 0; i < fld_cnt; i++) {
171
+ getters[i] = fields[i].name;
172
+ tbl_name = fields[i].org_name ? fields[i].org_name : fields[i].name;
173
+ strcat(tbl_name, "@");
174
+ strcat(tbl_name, fields[i].org_table ? fields[i].org_table : fields[i].table);
175
+ rb_ary_store(ary, i, rb_tainted_str_new2(tbl_name));
176
+ tbl_name = "";
177
+ castAs[i] = castPreWrk(fields[i].type);
178
+ }
179
+ rb_ary_push(res_set, ary);
180
+ while ((row = mysql_fetch_row(res)) != NULL) {
181
+ n = mysql_num_fields(res);
182
+ lengths = mysql_fetch_lengths(res);
183
+ ary = rb_ary_new2(n);
184
+ for (i = 0; i < n; i++) {
185
+ rb_ary_store(ary, i, row[i] ? castFrFetch(castAs[i], rb_tainted_str_new(row[i], lengths[i]), i) : Qnil);
186
+ //rb_define_singleton_method(ary, "{dynamic getters}", activeSQL_dyamic_meth, 0); WE CN ADD IF HV NEW WAY.
187
+ if (mysObj.adds == 0)
188
+ if (getters[i] != "") {
189
+ dyn_method = (char *) malloc(((unsigned int) strlen(getters[i]) + 21)); // **
190
+ sprintf(dyn_method, "def %s; self[%u]; end", getters[i], i);
191
+ cmd = rb_str_new2(dyn_method);
192
+ rb_obj_instance_eval(1, &cmd, ary);
193
+ free(dyn_method);
194
+ }
195
+ }
196
+ rb_ary_push(res_set, ary);
197
+ }
198
+
199
+ // FREE all.
200
+ free(getters);
201
+ free(castAs);
202
+ mysql_free_result(res);
203
+ return res_set;
204
+ }
205
+ else {
206
+ res = mysql_use_result(mysObj.conn); // To avoid out of sync error from api.
207
+ mysql_free_result(res);
208
+ return Qtrue; /* Add affacted rows instead of status if needed */
209
+ }
210
+ }
211
+ else
212
+ rb_raise(rb_eSqlError, "Connection not established.");
213
+ }
214
+
215
+ static VALUE activeSQL_connected(VALUE self) {
216
+ if (mysObj.reconnect == 0)
217
+ return Qtrue;
218
+ else
219
+ return Qfalse;
220
+ }
221
+
222
+ static VALUE activeSQL_disconnect(VALUE self) {
223
+ if (mysObj.reconnect == 0) {
224
+ mysObj.reconnect = 1;
225
+ mysql_close(mysObj.conn);
226
+ return Qtrue;
227
+ }
228
+ else
229
+ return Qfalse;
230
+ }
231
+
232
+ static VALUE activeSQL_reconnect(VALUE self) {
233
+ rb_funcall(rb_cBase, rb_intern("disconnect!"), 0);
234
+ return rb_funcall(rb_cBase, rb_intern("connect!"), 0);
235
+ }
236
+
237
+ static VALUE activeSQL_connect(VALUE self) {
238
+ if (mysObj.reconnect == 1) {
239
+ mysObj.conn = mysql_init(NULL);
240
+ if (!mysql_real_connect(mysObj.conn, myConfig.ser, myConfig.user, myConfig.pass, myConfig.db, myConfig.pp, myConfig.sock, myConfig.flg)) {
241
+ fprintf(stderr, "%s\n", mysql_error(mysObj.conn));
242
+ return Qfalse;
243
+ }
244
+ else {
245
+ mysObj.reconnect = 0;
246
+ return Qtrue;
247
+ }
248
+ }
249
+ else
250
+ return Qfalse;
251
+ }
252
+
253
+ static VALUE activeSQL_version(VALUE self) {
254
+ return rb_str_new("2.0.1", 5);
255
+ }
256
+
257
+ static VALUE activeSQL_load_config(int argc, VALUE *argv, VALUE self) {
258
+ VALUE host, user, passwd, db, port, sock, flag;
259
+ rb_scan_args(argc, argv, "07", &host, &user, &passwd, &db, &port, &sock, &flag);
260
+ myConfig.db = IfNILorSTRING(db);
261
+ myConfig.flg = IfNILorINT(flag);
262
+ myConfig.ser = IfNILorSTRING(host);
263
+ myConfig.user = IfNILorSTRING(user);
264
+ myConfig.pass = IfNILorSTRING(passwd);
265
+ myConfig.pp = IfNILorINT(port);
266
+ myConfig.sock = IfNILorSTRING(sock);
267
+ mysObj.reconnect = 1;
268
+ return Qnil;
269
+ }
270
+
271
+
272
+ // activeSQL
273
+ void Init_activesql() {
274
+ activeSQL = rb_define_module("ActiveSQL");
275
+ rb_cBase = rb_define_class_under(activeSQL, "Base", rb_cObject);
276
+ rb_eSqlError = rb_define_class("ActiveSQLError", rb_eStandardError);
277
+ rb_cCols = rb_define_class_under(activeSQL, "Cols", rb_cArray);
278
+ // methods visible.
279
+ rb_define_singleton_method(rb_cBase, "load_config", activeSQL_load_config, -1);
280
+ rb_define_singleton_method(rb_cBase, "version", activeSQL_version, 0);
281
+ rb_define_singleton_method(rb_cBase, "connect!", activeSQL_connect, 0);
282
+ rb_define_singleton_method(rb_cBase, "reconnect!", activeSQL_reconnect, 0);
283
+ rb_define_singleton_method(rb_cBase, "disconnect!", activeSQL_disconnect, 0);
284
+ rb_define_singleton_method(rb_cBase, "connected?", activeSQL_connected, 0);
285
+ rb_define_singleton_method(rb_cBase, "exec", activeSQL_exec, 2);
286
+ rb_define_singleton_method(rb_cBase, "my_char_set", activeSQL_set_chars_set, -1);
287
+ rb_define_singleton_method(rb_cBase, "exec_sql", activeSQL_exec_sql, 1);
288
+ rb_define_singleton_method(rb_cBase, "add_methods", activeSQL_add_methods, -1);
289
+ rb_define_singleton_method(rb_cBase, "add_methods?", activeSQL_added_methods, 0);
290
+ rb_define_singleton_method(rb_cBase, "my_database", activeSQL_my_database, -1);
291
+ rb_define_singleton_method(rb_cBase, "my_select?", activeSQL_my_select, 0);
292
+ //rb_define_singleton_method(rb_cBase, "auto_commit", activeSQL_auto_commit, 1);
293
+ init_active_sqls();
294
+ }
295
+
296
+ // Will work behind.
297
+ // static VALUE castFrFetch(unsigned int typ, char ** row, unsigned long len, unsigned int itr){
298
+
299
+ static VALUE castFrFetch(unsigned int typ, VALUE row, unsigned int itr) {
300
+ VALUE cst;
301
+ switch (typ){
302
+ case 1:
303
+ cst = rb_funcall2(row, rb_intern("to_i"), 0, NULL);
304
+ break;
305
+ case 2:
306
+ cst = rb_funcall2(row, rb_intern("to_f"), 0, NULL);
307
+ break;
308
+ case 3:
309
+ default:
310
+ return row;
311
+ }
312
+ return cst;
313
+ }
314
+
315
+ static int castPreWrk(enum enum_field_types typ) {
316
+ unsigned int ret;
317
+ switch (typ) {
318
+ case MYSQL_TYPE_SHORT:
319
+ case MYSQL_TYPE_INT24:
320
+ case MYSQL_TYPE_LONGLONG:
321
+ case MYSQL_TYPE_TINY:
322
+ case MYSQL_TYPE_LONG:
323
+ ret = 1;
324
+ break;
325
+ case MYSQL_TYPE_DECIMAL:
326
+ case MYSQL_TYPE_FLOAT:
327
+ case MYSQL_TYPE_DOUBLE:
328
+ ret = 2;
329
+ break;
330
+ case MYSQL_TYPE_TIMESTAMP:
331
+ case MYSQL_TYPE_DATE:
332
+ case MYSQL_TYPE_TIME:
333
+ case MYSQL_TYPE_DATETIME:
334
+ case MYSQL_TYPE_YEAR:
335
+ case MYSQL_TYPE_STRING:
336
+ case MYSQL_TYPE_VAR_STRING:
337
+ case MYSQL_TYPE_BLOB:
338
+ case MYSQL_TYPE_SET:
339
+ case MYSQL_TYPE_ENUM:
340
+ case MYSQL_TYPE_GEOMETRY:
341
+ case MYSQL_TYPE_NULL:
342
+ ret = 3;
343
+ break;
344
+ default:
345
+ ret = 3;
346
+ }
347
+ return ret;
348
+ }
349
+
350
+ static void init_active_sqls() {
351
+ mysObj.reconnect = 1;
352
+ // Append methods as getters.
353
+ mysObj.adds = 0;
354
+ }
Binary file
Binary file
@@ -7,3 +7,48 @@ rescue LoadError
7
7
  end
8
8
  end
9
9
 
10
+ module ActiveSQL
11
+ class Base
12
+ class << self
13
+
14
+ # Execute the sql queries.
15
+ def select_sql(qry)
16
+ if qry =~ my_select?
17
+ result = exec(qry, true)
18
+ cols = result.shift
19
+ result.instance_eval "def columns; #{cols.inspect}; end"
20
+ result
21
+ else
22
+ exec_sql(qry) # status.
23
+ end
24
+ end
25
+
26
+ # Result set not returned for execute_sql
27
+ def execute_sql(qry)
28
+ unless qry =~ my_select?
29
+ exec_sql(qry)
30
+ else
31
+ raise ActiveSQLError, "no return of result set"
32
+ end
33
+ end
34
+ alias :insert_sql :execute_sql
35
+
36
+ def establish_connection(config)
37
+ host = (config[:host] ||= 'localhost')
38
+ username = config[:username] ? config[:username].to_s : 'root'
39
+ password = config[:password] ? config[:password].to_s : ''
40
+ database = config[:database]
41
+ port = config[:port]
42
+ socket = config[:socket]
43
+ default_flags = 0
44
+ # No multi-results as of now.
45
+ options = [host, username, password, database, port, socket, default_flags]
46
+ load_config(*options)
47
+
48
+ # make connection across the parameters.
49
+ connect!
50
+ end
51
+
52
+ end
53
+ end
54
+ end
Binary file
data/readme.txt CHANGED
@@ -1,12 +1,55 @@
1
- Welcome :
2
- =========
3
-
4
- ActiveSQL is super fast.
1
+ ActiveSQL
2
+ ===========
3
+
4
+ Get the super fast mysql query results from Ruby and Rails applications.
5
+
6
+ Love to write queries.
5
7
 
6
- It works on mysql 5 or greater versions(tested under linux).
8
+ Build queries on your own.
9
+
10
+ Get super fast results.
11
+
12
+ Keep everything in mysql.
13
+
7
14
 
8
- Usage.
9
- ========
15
+ USAGE:
16
+ ======
17
+
18
+ require 'active_sql'
19
+
20
+ ActiveSQL::Base.establish_connection(:host=> 'localhost', :username=>'root', :password=> 'peep', :socket=> '') => true
21
+
22
+ ActiveSQL::Base.connected? => true
10
23
 
24
+ ActiveSQL::Base.insert_sql("insert into users values(1, user1@example.com, 12, 12.3)") => true
25
+
26
+ ActiveSQL::Base.execute_sql("delete from roles") => true
27
+
28
+ ActiveSQL::Base.select_sql("select * from users") => [[1, 'user1@example.com', 12, 12.3]]
29
+
30
+ ActiveSQL::Base.select_sql("select * from users").columns => ["id@users", "email@users", "rate@users", "points@users"]
11
31
 
32
+ user = ActiveSQL::Base.select_sql("select id, rate as rank from users limit 1").first
33
+ # Methods will be added by default.
34
+ # Disabling methods possible.
35
+ user.id => 1
36
+ user.rank => 12
37
+
38
+ ActiveSQL::Base.my_char_set => "latin1"
12
39
 
40
+ ActiveSQL::Base.my_char_set("utf8") => "utf8"
41
+
42
+ ActiveSQL::Base.my_database("another_database") => true
43
+
44
+ # Append get methods to every row.
45
+ ActiveSQL::Base.add_methods(true) => true
46
+
47
+ # Do not append methods:
48
+ ActiveSQL::Base.add_methods(false) => true
49
+
50
+ # Status of adding methods to the rows.
51
+ ActiveSQL::Base.add_methods? => true
52
+
53
+
54
+ Note:
55
+ Tentative build compiled by ruby 1.8 - linux.
metadata CHANGED
@@ -3,10 +3,10 @@ name: active_sql
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
- - 1
6
+ - 2
7
7
  - 0
8
8
  - 1
9
- version: 1.0.1
9
+ version: 2.0.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - sasie
@@ -14,12 +14,12 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2012-03-14 00:00:00 +05:30
17
+ date: 2012-04-12 00:00:00 +05:30
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
21
21
  description: Easy to work with mysql from ruby and rails
22
- email: sasie@rocketmail.com
22
+ email: sasieindrajit@gmail.com
23
23
  executables: []
24
24
 
25
25
  extensions: []
@@ -29,9 +29,12 @@ extra_rdoc_files: []
29
29
  files:
30
30
  - lib/activesql.so
31
31
  - lib/active_sql.rb
32
+ - ext/activesql.c
33
+ - ext/activesql.o
34
+ - ext/activesql.so
32
35
  - readme.txt
33
36
  has_rdoc: true
34
- homepage: http://github.com/
37
+ homepage: https://github.com/sasie-sourcebits/active_sql
35
38
  licenses: []
36
39
 
37
40
  post_install_message: