aerospike_native 0.1.2 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f9adbd76e01717770aa172758d38a3e9340abbec
4
- data.tar.gz: 5f95658e8a79c57d2021a5ae041c69300989372e
3
+ metadata.gz: bb3d554ba14a9cdc3064e7f710e1fd8e2f5303c9
4
+ data.tar.gz: 06b57fc85d271be4c845838f0918daf4e334a771
5
5
  SHA512:
6
- metadata.gz: f27395cdf1605ca3fb553f77220951adecd99b124ce28570948f3e46e063f17c50b6b8ccd7fb7e858a8abec94a6042c0e3f2325946833f621293fe574b3f2e4e
7
- data.tar.gz: 5220d3cc0b14b6c4f033e5831f092e9e485bddce1be9bd277fb9159ed47a322fd131e67c0abeecfb282b545ebb447f0b25d9e912f0a5e5d94134d634b4c66006
6
+ metadata.gz: 71bcee1166282f8a9cfb6a4df0ecb04f91ab86abc78f988c45fcee6c42f018b2b410a028b6ea74b4975c6bbe975d5a4db2c84b4a65933fe2ab43727a9798fa46
7
+ data.tar.gz: 688f5da01520a1686952f2f376bb093dd5b1450a181fdc7d5c727a955692b6ef56aadbff20b6440e6f718884bdff84e946beec9c1437bf59f72861dc19a9baf5
data/README.md CHANGED
@@ -55,8 +55,7 @@ client.remove(key)
55
55
  end
56
56
  client.create_index('test', 'test', 'number', 'number_idx');
57
57
 
58
- records = []
59
- client.where('test', 'test', [AerospikeNative::Condition.range("number", 1, 7)]) { |record| records << record }
58
+ records = client.query('test', 'test').where(number: [1, 7])
60
59
  puts records.inspect
61
60
  records.each { |record| client.remove(record.key) }
62
61
  ```
@@ -3,8 +3,8 @@
3
3
  #include "key.h"
4
4
  #include "operation.h"
5
5
  #include "record.h"
6
- #include "condition.h"
7
6
  #include "policy.h"
7
+ #include "query.h"
8
8
 
9
9
  VALUE AerospikeNativeClass;
10
10
 
@@ -13,12 +13,12 @@ void Init_aerospike_native()
13
13
  AerospikeNativeClass = rb_define_module("AerospikeNative");
14
14
  define_exception();
15
15
  define_logger();
16
- define_client();
16
+ define_query();
17
17
  define_native_key();
18
18
  define_record();
19
19
  define_operation();
20
- define_condition();
21
20
  define_policy();
21
+ define_client();
22
22
 
23
23
  rb_define_const(AerospikeNativeClass, "INDEX_NUMERIC", INT2FIX(INDEX_NUMERIC));
24
24
  rb_define_const(AerospikeNativeClass, "INDEX_STRING", INT2FIX(INDEX_STRING));
@@ -2,7 +2,7 @@
2
2
  #include "operation.h"
3
3
  #include "key.h"
4
4
  #include "record.h"
5
- #include "condition.h"
5
+ #include "query.h"
6
6
  #include <aerospike/as_key.h>
7
7
  #include <aerospike/as_operations.h>
8
8
  #include <aerospike/aerospike_key.h>
@@ -11,6 +11,15 @@
11
11
 
12
12
  VALUE ClientClass;
13
13
 
14
+ void check_aerospike_client(VALUE vKey)
15
+ {
16
+ char sName[] = "AerospikeNative::Client";
17
+
18
+ if (strcmp(sName, rb_obj_classname(vKey)) != 0) {
19
+ rb_raise(rb_eArgError, "Incorrect type (expected %s)", sName);
20
+ }
21
+ }
22
+
14
23
  static void client_deallocate(void *p)
15
24
  {
16
25
  aerospike* ptr = p;
@@ -35,7 +44,7 @@ static VALUE client_allocate(VALUE klass)
35
44
  * new() -> AerospikeNative::Client
36
45
  * new(hosts) -> AerospikeNative::Client
37
46
  *
38
- * initialize new client, use {'host' => ..., 'port' => ...} for each hosts element
47
+ * initialize new client, use \{'host' => ..., 'port' => ...\} for each hosts element
39
48
  */
40
49
  VALUE client_initialize(int argc, VALUE* argv, VALUE self)
41
50
  {
@@ -141,6 +150,9 @@ VALUE client_put(int argc, VALUE* vArgs, VALUE vSelf)
141
150
  Check_Type(bin_name, T_STRING);
142
151
 
143
152
  switch( TYPE(bin_value) ) {
153
+ case T_NIL:
154
+ as_record_set_nil(&record, StringValueCStr(bin_name));
155
+ break;
144
156
  case T_STRING:
145
157
  as_record_set_str(&record, StringValueCStr(bin_name), StringValueCStr(bin_value));
146
158
  break;
@@ -148,7 +160,7 @@ VALUE client_put(int argc, VALUE* vArgs, VALUE vSelf)
148
160
  as_record_set_int64(&record, StringValueCStr(bin_name), NUM2LONG(bin_value));
149
161
  break;
150
162
  default:
151
- rb_raise(rb_eTypeError, "wrong argument type for bin value (expected Fixnum or String)");
163
+ rb_raise(rb_eTypeError, "wrong argument type for bin value (expected Nil, Fixnum or String)");
152
164
  break;
153
165
  }
154
166
  }
@@ -258,12 +270,24 @@ VALUE client_operate(int argc, VALUE* vArgs, VALUE vSelf)
258
270
  switch( op_type ) {
259
271
  case OPERATION_WRITE:
260
272
  switch( TYPE(bin_value) ) {
273
+ case T_NIL: {
274
+ as_record rec;
275
+ as_record_inita(&rec, 1);
276
+ as_record_set_nil(&rec, StringValueCStr( bin_name ));
277
+ ops.binops.entries[ops.binops.size].op = AS_OPERATOR_WRITE;
278
+ ops.binops.entries[ops.binops.size].bin = rec.bins.entries[0];
279
+ ops.binops.size++;
280
+ break;
281
+ }
261
282
  case T_STRING:
262
283
  as_operations_add_write_str(&ops, StringValueCStr( bin_name ), StringValueCStr( bin_value ));
263
284
  break;
264
285
  case T_FIXNUM:
265
286
  as_operations_add_write_int64(&ops, StringValueCStr( bin_name ), NUM2LONG( bin_value ));
266
287
  break;
288
+ default:
289
+ rb_raise(rb_eTypeError, "wrong argument type for bin value (expected Nil, Fixnum or String)");
290
+ break;
267
291
  }
268
292
 
269
293
  break;
@@ -468,7 +492,7 @@ VALUE client_select(int argc, VALUE* vArgs, VALUE vSelf)
468
492
  * create_index(namespace, set, bin_name, index_name) -> true or false
469
493
  * create_index(namespace, set, bin_name, index_name, policy_settings) -> true or false
470
494
  *
471
- * Create new index, use {'type' => AerospikeNative::INDEX_NUMERIC or AerospikeNative::INDEX_STRING} as policy_settings to define index type
495
+ * Create new index, use \{'type' => AerospikeNative::INDEX_NUMERIC or AerospikeNative::INDEX_STRING\} as policy_settings to define index type
472
496
  */
473
497
  VALUE client_create_index(int argc, VALUE* vArgs, VALUE vSelf)
474
498
  {
@@ -575,129 +599,22 @@ VALUE client_drop_index(int argc, VALUE* vArgs, VALUE vSelf)
575
599
  return Qtrue;
576
600
  }
577
601
 
578
- bool query_callback(const as_val *value, void *udata) {
579
- VALUE vRecord;
580
- as_record *record;
581
-
582
- if (value == NULL) {
583
- // query is complete
584
- return true;
585
- }
586
-
587
- record = as_record_fromval(value);
588
-
589
- if (record != NULL) {
590
- vRecord = rb_record_from_c(record, NULL);
591
-
592
- if ( rb_block_given_p() ) {
593
- rb_yield(vRecord);
594
- } else {
595
- VALUE *vArray = (VALUE*) udata;
596
- rb_ary_push(*vArray, vRecord);
597
- }
598
- }
599
-
600
- return true;
601
- }
602
602
 
603
603
  /*
604
604
  * call-seq:
605
- * where(namespace, set) -> array
606
- * where(namespace, set, conditions) -> array
607
- * where(namespace, set, conditions, policy_settings) -> array
608
- * where(namespace, set) { |record| ... } -> nil
609
- * where(namespace, set, conditions) { |record| ... } -> nil
610
- * where(namespace, set, conditions, policy_settings) { |record| ... } -> nil
605
+ * where(namespace, set) -> AerospikeNative::Query
611
606
  *
612
- * Perform a query with where clause
607
+ * Instanciate new query
613
608
  */
614
- VALUE client_exec_query(int argc, VALUE* vArgs, VALUE vSelf)
609
+ VALUE client_query(VALUE vSelf, VALUE vNamespace, VALUE vSet)
615
610
  {
616
- VALUE vNamespace;
617
- VALUE vSet;
618
- VALUE vConditions;
619
- VALUE vArray;
620
-
621
- aerospike *ptr;
622
- as_error err;
623
- as_policy_query policy;
624
- as_query query;
625
-
626
- int idx = 0, n = 0;
627
-
628
- if (argc > 4 || argc < 2) { // there should only be 2, 3 or 4 arguments
629
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..4)", argc);
630
- }
631
-
632
- vNamespace = vArgs[0];
633
- Check_Type(vNamespace, T_STRING);
611
+ VALUE vParams[3];
634
612
 
635
- vSet = vArgs[1];
636
- Check_Type(vSet, T_STRING);
637
-
638
- vConditions = vArgs[2];
639
- switch(TYPE(vConditions)) {
640
- case T_NIL:
641
- break;
642
- case T_ARRAY:
643
- idx = RARRAY_LEN(vConditions);
644
- break;
645
- default:
646
- rb_raise(rb_eTypeError, "wrong argument type for condition (expected Array or Nil)");
647
- }
648
-
649
- as_policy_query_init(&policy);
650
- if (argc == 4 && TYPE(vArgs[3]) != T_NIL) {
651
- SET_POLICY(policy, vArgs[3]);
652
- }
653
-
654
- Data_Get_Struct(vSelf, aerospike, ptr);
655
-
656
- as_query_init(&query, StringValueCStr(vNamespace), StringValueCStr(vSet));
657
- as_query_where_inita(&query, idx);
658
- for(n = 0; n < idx; n++) {
659
- VALUE vMin, vMax, vBinName;
660
- VALUE vCondition = rb_ary_entry(vConditions, n);
661
- check_aerospike_condition(vCondition);
662
- vMin = rb_iv_get(vCondition, "@min");
663
- vMax = rb_iv_get(vCondition, "@max");
664
- vBinName = rb_iv_get(vCondition, "@bin_name");
665
-
666
- switch(TYPE(vMin)) {
667
- case T_FIXNUM:
668
- switch(TYPE(vMax)) {
669
- case T_NIL:
670
- as_query_where(&query, StringValueCStr(vBinName), as_integer_equals(FIX2LONG(vMin)));
671
- break;
672
- case T_FIXNUM:
673
- as_query_where(&query, StringValueCStr(vBinName), as_integer_range(FIX2LONG(vMin), FIX2LONG(vMax)));
674
- break;
675
- default:
676
- rb_raise(rb_eArgError, "Incorrect condition");
677
- }
678
-
679
- break;
680
- case T_STRING:
681
- Check_Type(vMax, T_NIL);
682
- as_query_where(&query, StringValueCStr(vBinName), as_string_equals(StringValueCStr(vMin)));
683
- break;
684
- default:
685
- rb_raise(rb_eArgError, "Incorrect condition");
686
- }
687
- }
688
-
689
- vArray = rb_ary_new();
690
- if (aerospike_query_foreach(ptr, &err, &policy, &query, query_callback, &vArray) != AEROSPIKE_OK) {
691
- as_query_destroy(&query);
692
- raise_aerospike_exception(err.code, err.message);
693
- }
694
- as_query_destroy(&query);
695
-
696
- if ( rb_block_given_p() ) {
697
- return Qnil;
698
- }
613
+ vParams[0] = vSelf;
614
+ vParams[1] = vNamespace;
615
+ vParams[2] = vSet;
699
616
 
700
- return vArray;
617
+ return rb_class_new_instance(3, vParams, QueryClass);
701
618
  }
702
619
 
703
620
  VALUE client_set_logger(VALUE vSelf, VALUE vNewLogger)
@@ -729,7 +646,7 @@ void define_client()
729
646
  rb_define_method(ClientClass, "select", client_select, -1);
730
647
  rb_define_method(ClientClass, "create_index", client_create_index, -1);
731
648
  rb_define_method(ClientClass, "drop_index", client_drop_index, -1);
732
- rb_define_method(ClientClass, "where", client_exec_query, -1);
649
+ rb_define_method(ClientClass, "query", client_query, 2);
733
650
 
734
651
  rb_cv_set(ClientClass, "@@logger", rb_class_new_instance(0, NULL, LoggerClass));
735
652
  rb_define_singleton_method(ClientClass, "set_logger", client_set_logger, 1);
@@ -5,5 +5,6 @@
5
5
 
6
6
  RUBY_EXTERN VALUE ClientClass;
7
7
  void define_client();
8
+ void check_aerospike_client(VALUE vKey);
8
9
 
9
10
  #endif // CLIENT_H
@@ -7,6 +7,16 @@
7
7
 
8
8
  VALUE rb_hash_keys(VALUE hash);
9
9
 
10
+ #define GET_STRING(vString) \
11
+ switch(TYPE(vString)) { \
12
+ case T_SYMBOL: \
13
+ vString = rb_sym_to_s(vString); \
14
+ case T_STRING: \
15
+ break; \
16
+ default: \
17
+ rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)"); \
18
+ }
19
+
10
20
  #define SET_POLICY(policy, vSettings) \
11
21
  VALUE vTimeout; \
12
22
  Check_Type(vSettings, T_HASH); \
@@ -81,10 +81,10 @@ VALUE key_initialize(int argc, VALUE* vArgs, VALUE vSelf)
81
81
 
82
82
  void check_aerospike_key(VALUE vKey)
83
83
  {
84
- char sKeyName[] = "AerospikeNative::Key";
84
+ char sName[] = "AerospikeNative::Key";
85
85
 
86
- if (strcmp(sKeyName, rb_obj_classname(vKey)) != 0) {
87
- rb_raise(rb_eArgError, "Incorrect type (expected %s)", sKeyName);
86
+ if (strcmp(sName, rb_obj_classname(vKey)) != 0) {
87
+ rb_raise(rb_eArgError, "Incorrect type (expected %s)", sName);
88
88
  }
89
89
  }
90
90
 
@@ -7,7 +7,6 @@ bool aerospike_log_callback(as_log_level level, const char *func, const char *fi
7
7
  uint32_t line, const char *fmt, ...)
8
8
  {
9
9
  char msg[1024] = {0};
10
- char log_msg[1500] = {0};
11
10
  va_list ap;
12
11
  VALUE vLogger = rb_cv_get(ClientClass, "@@logger");
13
12
 
@@ -16,10 +15,8 @@ bool aerospike_log_callback(as_log_level level, const char *func, const char *fi
16
15
  msg[1023] = '\0';
17
16
  va_end(ap);
18
17
 
19
- sprintf(log_msg, "%d (Aerospike) - %s", level, msg);
20
-
21
18
  if(TYPE(vLogger) != T_NIL) {
22
- rb_funcall(vLogger, rb_intern("write"), 2, INT2FIX(level), rb_str_new2(log_msg));
19
+ rb_funcall(vLogger, rb_intern("write"), 2, INT2FIX(level), rb_str_new2(msg));
23
20
  }
24
21
 
25
22
  return true;
@@ -86,6 +83,26 @@ VALUE logger_write(VALUE vSelf, VALUE vLevel, VALUE vMsg)
86
83
  switch(TYPE(vInternalLogger)) {
87
84
  case T_NIL:
88
85
  if (level <= FIX2INT(vInternalLevel)) {
86
+ switch(level) {
87
+ case AS_LOG_LEVEL_ERROR:
88
+ vMsg = rb_str_plus(rb_str_new2("ERROR (AEROSPIKE): "), vMsg);
89
+ break;
90
+ case AS_LOG_LEVEL_WARN:
91
+ vMsg = rb_str_plus(rb_str_new2("WARN (AEROSPIKE): "), vMsg);
92
+ break;
93
+ case AS_LOG_LEVEL_INFO:
94
+ vMsg = rb_str_plus(rb_str_new2("INFO (AEROSPIKE): "), vMsg);
95
+ break;
96
+ case AS_LOG_LEVEL_DEBUG:
97
+ vMsg = rb_str_plus(rb_str_new2("DEBUG (AEROSPIKE): "), vMsg);
98
+ break;
99
+ case AS_LOG_LEVEL_TRACE:
100
+ vMsg = rb_str_plus(rb_str_new2("DEBUG (AEROSPIKE): "), vMsg);
101
+ break;
102
+ default:
103
+ vMsg = rb_str_plus(rb_str_new2("UNKNOWN (AEROSPIKE): "), vMsg);
104
+ break;
105
+ }
89
106
  // TODO: add default behavior with write into file
90
107
  fprintf(stdout, "%s\n", StringValueCStr(vMsg));
91
108
  return vMsg;
@@ -0,0 +1,318 @@
1
+ #include "query.h"
2
+ #include "client.h"
3
+ #include "record.h"
4
+ #include <aerospike/aerospike_query.h>
5
+
6
+ VALUE QueryClass;
7
+
8
+ VALUE query_initialize(VALUE vSelf, VALUE vClient, VALUE vNamespace, VALUE vSet)
9
+ {
10
+ Check_Type(vNamespace, T_STRING);
11
+ Check_Type(vSet, T_STRING);
12
+ check_aerospike_client(vClient);
13
+
14
+ rb_iv_set(vSelf, "@client", vClient);
15
+ rb_iv_set(vSelf, "@namespace", vNamespace);
16
+ rb_iv_set(vSelf, "@set", vSet);
17
+
18
+ return vSelf;
19
+ }
20
+
21
+ VALUE query_select(int argc, VALUE* vArgs, VALUE vSelf)
22
+ {
23
+ VALUE vBins;
24
+ int i;
25
+
26
+ if (argc == 0) { // there should be greater than 0
27
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..n)", argc);
28
+ }
29
+
30
+ vBins = rb_iv_get(vSelf, "@select_bins");
31
+ if(TYPE(vBins) == T_NIL) {
32
+ vBins = rb_ary_new();
33
+ }
34
+ if (argc == 1) {
35
+ int idx;
36
+ VALUE vArray = vArgs[0];
37
+ Check_Type(vArray, T_ARRAY);
38
+ idx = RARRAY_LEN(vArray);
39
+ for(i = 0; i < idx; i++) {
40
+ VALUE vString = rb_ary_entry(vArray, i);
41
+ GET_STRING(vString);
42
+ rb_ary_push(vBins, vString);
43
+ }
44
+ } else {
45
+ for(i = 0; i < argc; i++) {
46
+ VALUE vString = vArgs[i];
47
+ GET_STRING(vString);
48
+ rb_ary_push(vBins, vString);
49
+ }
50
+ }
51
+
52
+ rb_iv_set(vSelf, "@select_bins", vBins);
53
+ return vSelf;
54
+ }
55
+
56
+ int query_order_hash_foreach(VALUE vKey, VALUE vValue, VALUE vHash)
57
+ {
58
+ VALUE vHashKey, vHashValue;
59
+ VALUE vAsc, vDesc;
60
+
61
+ vAsc = ID2SYM( rb_intern("asc") );
62
+ vDesc = ID2SYM( rb_intern("desc") );
63
+
64
+ Check_Type(vValue, T_SYMBOL);
65
+ vHashKey = vKey;
66
+ GET_STRING(vHashKey);
67
+ if(vValue != vAsc && vValue != vDesc) {
68
+ rb_raise(rb_eArgError, "expected :asc or :desc for value");
69
+ }
70
+
71
+ if(vValue == vAsc) {
72
+ vHashValue = INT2NUM(AS_ORDER_ASCENDING);
73
+ } else {
74
+ vHashValue = INT2NUM(AS_ORDER_DESCENDING);
75
+ }
76
+
77
+ rb_hash_aset(vHash, vHashKey, vHashValue);
78
+
79
+ return ST_CONTINUE;
80
+ }
81
+
82
+ VALUE query_order(VALUE vSelf, VALUE vHash)
83
+ {
84
+ VALUE vBins;
85
+ Check_Type(vHash, T_HASH);
86
+
87
+ vBins = rb_iv_get(vSelf, "@order_bins");
88
+ if(TYPE(vBins) == T_NIL) {
89
+ vBins = rb_hash_new();
90
+ }
91
+ rb_hash_foreach(vHash, query_order_hash_foreach, vBins);
92
+ rb_iv_set(vSelf, "@order_bins", vBins);
93
+ return vSelf;
94
+ }
95
+
96
+ int query_where_hash_foreach(VALUE vKey, VALUE vValue, VALUE vHash)
97
+ {
98
+ VALUE vHashKey, vHashValue;
99
+ int idx;
100
+
101
+ vHashKey = vKey;
102
+ GET_STRING(vHashKey);
103
+
104
+ switch(TYPE(vValue)) {
105
+ case T_ARRAY:
106
+ idx = RARRAY_LEN(vValue);
107
+ if (idx != 2) {
108
+ rb_raise(rb_eArgError, "wrong array length (expected 2 elements)");
109
+ }
110
+ vHashValue = vValue;
111
+ break;
112
+ case T_FIXNUM:
113
+ case T_STRING:
114
+ vHashValue = vValue;
115
+ break;
116
+ default:
117
+ rb_raise(rb_eTypeError, "wrong argument type for (expected Array, String or Fixnum)");
118
+ }
119
+
120
+ rb_hash_aset(vHash, vHashKey, vHashValue);
121
+
122
+ return ST_CONTINUE;
123
+ }
124
+
125
+ VALUE query_where(VALUE vSelf, VALUE vHash)
126
+ {
127
+ VALUE vBins;
128
+ Check_Type(vHash, T_HASH);
129
+
130
+ vBins = rb_iv_get(vSelf, "@where_bins");
131
+ if(TYPE(vBins) == T_NIL) {
132
+ vBins = rb_hash_new();
133
+ }
134
+ rb_hash_foreach(vHash, query_where_hash_foreach, vBins);
135
+ rb_iv_set(vSelf, "@where_bins", vBins);
136
+ return vSelf;
137
+ }
138
+
139
+ bool query_callback(const as_val *value, void *udata) {
140
+ VALUE vRecord;
141
+ as_record *record;
142
+
143
+ if (value == NULL) {
144
+ // query is complete
145
+ return true;
146
+ }
147
+
148
+ record = as_record_fromval(value);
149
+
150
+ if (record != NULL) {
151
+ vRecord = rb_record_from_c(record, NULL);
152
+
153
+ if ( rb_block_given_p() ) {
154
+ rb_yield(vRecord);
155
+ } else {
156
+ VALUE *vArray = (VALUE*) udata;
157
+ rb_ary_push(*vArray, vRecord);
158
+ }
159
+ }
160
+
161
+ return true;
162
+ }
163
+
164
+ VALUE query_exec(int argc, VALUE* vArgs, VALUE vSelf)
165
+ {
166
+ VALUE vNamespace;
167
+ VALUE vSet;
168
+ VALUE vArray;
169
+ VALUE vClient;
170
+ VALUE vWhere, vSelect, vOrder;
171
+ VALUE vWhereKeys, vOrderKeys;
172
+
173
+ aerospike *ptr;
174
+ as_error err;
175
+ as_policy_query policy;
176
+ as_query query;
177
+
178
+ int n = 0;
179
+ int where_idx = 0, select_idx = 0, order_idx = 0;
180
+
181
+ if (argc > 1) { // there should only be 0 or 1 arguments
182
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc);
183
+ }
184
+
185
+ vNamespace = rb_iv_get(vSelf, "@namespace");
186
+ vSet = rb_iv_get(vSelf, "@set");
187
+
188
+ vWhere = rb_iv_get(vSelf, "@where_bins");
189
+ switch(TYPE(vWhere)) {
190
+ case T_NIL:
191
+ break;
192
+ case T_HASH:
193
+ vWhereKeys = rb_hash_keys(vWhere);
194
+ where_idx = RARRAY_LEN(vWhereKeys);
195
+ break;
196
+ default:
197
+ rb_raise(rb_eTypeError, "wrong argument type for where (expected Hash or Nil)");
198
+ }
199
+
200
+ vSelect = rb_iv_get(vSelf, "@select_bins");
201
+ switch(TYPE(vSelect)) {
202
+ case T_NIL:
203
+ break;
204
+ case T_ARRAY:
205
+ select_idx = RARRAY_LEN(vSelect);
206
+ break;
207
+ default:
208
+ rb_raise(rb_eTypeError, "wrong argument type for select (expected Array or Nil)");
209
+ }
210
+
211
+ vOrder = rb_iv_get(vSelf, "@order_bins");
212
+ switch(TYPE(vOrder)) {
213
+ case T_NIL:
214
+ break;
215
+ case T_HASH:
216
+ vOrderKeys = rb_hash_keys(vOrder);
217
+ order_idx = RARRAY_LEN(vOrderKeys);
218
+ break;
219
+ default:
220
+ rb_raise(rb_eTypeError, "wrong argument type for order (expected Hash or Nil)");
221
+ }
222
+
223
+ as_policy_query_init(&policy);
224
+ if (argc == 1 && TYPE(vArgs[0]) != T_NIL) {
225
+ SET_POLICY(policy, vArgs[0]);
226
+ }
227
+
228
+ vClient = rb_iv_get(vSelf, "@client");
229
+ Data_Get_Struct(vClient, aerospike, ptr);
230
+
231
+ as_query_init(&query, StringValueCStr(vNamespace), StringValueCStr(vSet));
232
+
233
+ as_query_select_inita(&query, select_idx);
234
+ for(n = 0; n < select_idx; n++) {
235
+ VALUE vBinName;
236
+ vBinName = rb_ary_entry(vSelect, n);
237
+
238
+ as_query_select(&query, StringValueCStr(vBinName));
239
+ }
240
+
241
+ as_query_orderby_inita(&query, order_idx);
242
+ for(n = 0; n < order_idx; n++) {
243
+ VALUE vBinName;
244
+ VALUE vCondition;
245
+ vBinName = rb_ary_entry(vOrderKeys, n);
246
+ vCondition = rb_hash_aref(vOrder, vBinName);
247
+
248
+ as_query_orderby(&query, StringValueCStr(vBinName), NUM2INT(vCondition));
249
+ }
250
+
251
+ as_query_where_inita(&query, where_idx);
252
+ for(n = 0; n < where_idx; n++) {
253
+ VALUE vMin = Qnil, vMax = Qnil, vBinName;
254
+ VALUE vCondition;
255
+ vBinName = rb_ary_entry(vWhereKeys, n);
256
+ vCondition = rb_hash_aref(vWhere, vBinName);
257
+ switch(TYPE(vCondition)) {
258
+ case T_ARRAY:
259
+ vMin = rb_ary_entry(vCondition, 0);
260
+ vMax = rb_ary_entry(vCondition, 1);
261
+ break;
262
+ default:
263
+ vMin = vCondition;
264
+ }
265
+
266
+ switch(TYPE(vMin)) {
267
+ case T_FIXNUM:
268
+ switch(TYPE(vMax)) {
269
+ case T_NIL:
270
+ as_query_where(&query, StringValueCStr(vBinName), as_integer_equals(FIX2LONG(vMin)));
271
+ break;
272
+ case T_FIXNUM:
273
+ as_query_where(&query, StringValueCStr(vBinName), as_integer_range(FIX2LONG(vMin), FIX2LONG(vMax)));
274
+ break;
275
+ default:
276
+ rb_raise(rb_eArgError, "Incorrect condition");
277
+ }
278
+
279
+ break;
280
+ case T_STRING:
281
+ Check_Type(vMax, T_NIL);
282
+ as_query_where(&query, StringValueCStr(vBinName), as_string_equals(StringValueCStr(vMin)));
283
+ break;
284
+ default:
285
+ rb_raise(rb_eArgError, "Incorrect condition");
286
+ }
287
+ }
288
+
289
+ vArray = rb_ary_new();
290
+ if (aerospike_query_foreach(ptr, &err, &policy, &query, query_callback, &vArray) != AEROSPIKE_OK) {
291
+ as_query_destroy(&query);
292
+ raise_aerospike_exception(err.code, err.message);
293
+ }
294
+ as_query_destroy(&query);
295
+
296
+ if ( rb_block_given_p() ) {
297
+ return Qnil;
298
+ }
299
+
300
+ return vArray;
301
+ }
302
+
303
+ void define_query()
304
+ {
305
+ QueryClass = rb_define_class_under(AerospikeNativeClass, "Query", rb_cObject);
306
+ rb_define_method(QueryClass, "initialize", query_initialize, 3);
307
+ rb_define_method(QueryClass, "select", query_select, -1);
308
+ rb_define_method(QueryClass, "order", query_order, 1);
309
+ rb_define_method(QueryClass, "where", query_where, 1);
310
+ rb_define_method(QueryClass, "exec", query_exec, -1);
311
+
312
+ rb_define_attr(QueryClass, "client", 1, 0);
313
+ rb_define_attr(QueryClass, "namespace", 1, 0);
314
+ rb_define_attr(QueryClass, "set", 1, 0);
315
+ rb_define_attr(QueryClass, "select_bins", 1, 0);
316
+ rb_define_attr(QueryClass, "where_bins", 1, 0);
317
+ rb_define_attr(QueryClass, "order_bins", 1, 0);
318
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef QUERY_H
2
+ #define QUERY_H
3
+
4
+ #include "aerospike_native.h"
5
+
6
+ RUBY_EXTERN VALUE QueryClass;
7
+ void define_query();
8
+
9
+ #endif // QUERY_H
10
+
@@ -1,5 +1,6 @@
1
1
  #include "record.h"
2
2
  #include "key.h"
3
+ #include "client.h"
3
4
 
4
5
  VALUE RecordClass;
5
6
 
@@ -27,9 +28,11 @@ VALUE record_initialize(VALUE vSelf, VALUE vKey, VALUE vBins, VALUE vGen, VALUE
27
28
  VALUE rb_record_from_c(as_record* record, as_key* key)
28
29
  {
29
30
  VALUE vKeyParams[5], vParams[4];
31
+ VALUE vLogger;
30
32
  as_key current_key;
31
33
  as_bin bin;
32
34
  int n;
35
+ char msg[200];
33
36
 
34
37
  if (key == NULL) {
35
38
  current_key = record->key;
@@ -43,7 +46,12 @@ VALUE rb_record_from_c(as_record* record, as_key* key)
43
46
  if (current_key.valuep == NULL) {
44
47
  vKeyParams[2] = Qnil;
45
48
  } else {
46
- vKeyParams[2] = rb_str_new2(current_key.value.string.value);
49
+ char *str = current_key.value.string.value;
50
+ if (str == NULL) {
51
+ vKeyParams[2] = INT2NUM(current_key.value.integer.value);
52
+ } else {
53
+ vKeyParams[2] = rb_str_new2(str);
54
+ }
47
55
  }
48
56
  vKeyParams[3] = rb_str_new(current_key.digest.value, AS_DIGEST_VALUE_SIZE);
49
57
 
@@ -55,6 +63,9 @@ VALUE rb_record_from_c(as_record* record, as_key* key)
55
63
  for(n = 0; n < record->bins.size; n++) {
56
64
  bin = record->bins.entries[n];
57
65
  switch( as_val_type(bin.valuep) ) {
66
+ case AS_NIL:
67
+ rb_hash_aset(vParams[1], rb_str_new2(bin.name), Qnil);
68
+ break;
58
69
  case AS_INTEGER:
59
70
  rb_hash_aset(vParams[1], rb_str_new2(bin.name), LONG2NUM(bin.valuep->integer.value));
60
71
  break;
@@ -63,6 +74,9 @@ VALUE rb_record_from_c(as_record* record, as_key* key)
63
74
  break;
64
75
  case AS_UNDEF:
65
76
  default:
77
+ vLogger = rb_cv_get(ClientClass, "@@logger");
78
+ sprintf(msg, "unhandled val type: %d\n", as_val_type(bin.valuep));
79
+ rb_funcall(vLogger, rb_intern("warn"), 1, rb_str_new2(msg));
66
80
  break;
67
81
  }
68
82
  }
@@ -1,3 +1,3 @@
1
1
  module AerospikeNative
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aerospike_native
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Ziablitskii
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-14 00:00:00.000000000 Z
11
+ date: 2015-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -87,8 +87,6 @@ files:
87
87
  - ext/aerospike_native/client.h
88
88
  - ext/aerospike_native/common.c
89
89
  - ext/aerospike_native/common.h
90
- - ext/aerospike_native/condition.c
91
- - ext/aerospike_native/condition.h
92
90
  - ext/aerospike_native/exception.c
93
91
  - ext/aerospike_native/exception.h
94
92
  - ext/aerospike_native/extconf.rb
@@ -102,6 +100,8 @@ files:
102
100
  - ext/aerospike_native/operation.h
103
101
  - ext/aerospike_native/policy.c
104
102
  - ext/aerospike_native/policy.h
103
+ - ext/aerospike_native/query.c
104
+ - ext/aerospike_native/query.h
105
105
  - ext/aerospike_native/record.c
106
106
  - ext/aerospike_native/record.h
107
107
  - lib/aerospike_native.rb
@@ -1,125 +0,0 @@
1
- #include "condition.h"
2
-
3
- VALUE ConditionClass;
4
-
5
- void check_aerospike_condition(VALUE vKey)
6
- {
7
- char sName[] = "AerospikeNative::Condition";
8
-
9
- if (strcmp(sName, rb_obj_classname(vKey)) != 0) {
10
- rb_raise(rb_eArgError, "Incorrect type (expected %s)", sName);
11
- }
12
- }
13
-
14
- VALUE condition_initialize(VALUE vSelf, VALUE vBinName, VALUE vIndexType, VALUE vDataType, VALUE vMin, VALUE vMax)
15
- {
16
- int index_type = 0, data_type = 0;
17
- Check_Type(vBinName, T_STRING);
18
- Check_Type(vIndexType, T_FIXNUM);
19
- Check_Type(vDataType, T_FIXNUM);
20
-
21
- index_type = NUM2INT(vIndexType);
22
- data_type = NUM2INT(vDataType);
23
-
24
- switch(index_type) {
25
- case INDEX_NUMERIC:
26
- Check_Type(vMin, T_FIXNUM);
27
- switch(TYPE(vMax)) {
28
- case T_NIL:
29
- case T_FIXNUM:
30
- break;
31
- default:
32
- rb_raise(rb_eTypeError, "wrong argument type for max value (expected Fixnum or Nil)");
33
- }
34
- break;
35
- case INDEX_STRING:
36
- Check_Type(vMin, T_STRING);
37
- switch(TYPE(vMax)) {
38
- case T_NIL:
39
- case T_STRING:
40
- break;
41
- default:
42
- rb_raise(rb_eTypeError, "wrong argument type for max value (expected String or Nil)");
43
- }
44
- break;
45
- default:
46
- rb_raise(rb_eArgError, "Incorrect index type");
47
- }
48
-
49
- switch(data_type) {
50
- case CONDITION_TYPE_DEFAULT:
51
- case CONDITION_TYPE_LIST:
52
- case CONDITION_TYPE_MAPKEYS:
53
- case CONDITION_TYPE_MAPVALUES:
54
- break;
55
- default:
56
- rb_raise(rb_eArgError, "Incorrect data type");
57
- }
58
-
59
- rb_iv_set(vSelf, "@bin_name", vBinName);
60
- rb_iv_set(vSelf, "@index_type", vIndexType);
61
- rb_iv_set(vSelf, "@data_type", vDataType);
62
- rb_iv_set(vSelf, "@min", vMin);
63
- rb_iv_set(vSelf, "@max", vMax);
64
-
65
- return vSelf;
66
- }
67
-
68
- VALUE condition_equal(VALUE vSelf, VALUE vBinName, VALUE vVal)
69
- {
70
- VALUE vArgs[5];
71
- int index_type;
72
-
73
- Check_Type(vBinName, T_STRING);
74
-
75
- switch(TYPE(vVal)) {
76
- case T_FIXNUM:
77
- index_type = INDEX_NUMERIC;
78
- break;
79
- case T_STRING:
80
- index_type = INDEX_STRING;
81
- break;
82
- default:
83
- rb_raise(rb_eTypeError, "wrong argument type for value (expected Fixnum or String)");
84
- }
85
-
86
- vArgs[0] = vBinName;
87
- vArgs[1] = INT2FIX(index_type);
88
- vArgs[2] = INT2FIX(CONDITION_TYPE_DEFAULT);
89
- vArgs[3] = vVal;
90
- vArgs[4] = Qnil;
91
- return rb_class_new_instance(5, vArgs, vSelf);
92
- }
93
-
94
- VALUE condition_range(VALUE vSelf, VALUE vBinName, VALUE vMin, VALUE vMax)
95
- {
96
- VALUE vArgs[5];
97
-
98
- Check_Type(vBinName, T_STRING);
99
- Check_Type(vMin, T_FIXNUM);
100
- Check_Type(vMax, T_FIXNUM);
101
-
102
- vArgs[0] = vBinName;
103
- vArgs[1] = INT2FIX(INDEX_NUMERIC);
104
- vArgs[2] = INT2FIX(CONDITION_TYPE_DEFAULT);
105
- vArgs[3] = vMin;
106
- vArgs[4] = vMax;
107
- return rb_class_new_instance(5, vArgs, vSelf);
108
- }
109
-
110
- void define_condition()
111
- {
112
- ConditionClass = rb_define_class_under(AerospikeNativeClass, "Condition", rb_cObject);
113
- rb_define_method(ConditionClass, "initialize", condition_initialize, 5);
114
- rb_define_singleton_method(ConditionClass, "equal", condition_equal, 2);
115
- rb_define_singleton_method(ConditionClass, "range", condition_range, 3);
116
-
117
- rb_define_attr(ConditionClass, "bin_name", 1, 0);
118
- rb_define_attr(ConditionClass, "index_type", 1, 0);
119
- rb_define_attr(ConditionClass, "data_type", 1, 0);
120
- rb_define_attr(ConditionClass, "min", 1, 0);
121
- rb_define_attr(ConditionClass, "max", 1, 0);
122
- }
123
-
124
-
125
-
@@ -1,18 +0,0 @@
1
- #ifndef CONDITION_H
2
- #define CONDITION_H
3
-
4
- #include "aerospike_native.h"
5
-
6
- RUBY_EXTERN VALUE ConditionClass;
7
- void define_condition();
8
- void check_aerospike_condition(VALUE vKey);
9
-
10
- enum ConditionType {
11
- CONDITION_TYPE_DEFAULT = AS_INDEX_TYPE_DEFAULT,
12
- CONDITION_TYPE_LIST = AS_INDEX_TYPE_LIST,
13
- CONDITION_TYPE_MAPKEYS = AS_INDEX_TYPE_MAPKEYS,
14
- CONDITION_TYPE_MAPVALUES = AS_INDEX_TYPE_MAPVALUES
15
- };
16
-
17
- #endif // CONDITION_H
18
-