flydata 0.5.12 → 0.5.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 82270f47e1280076e3dc0b40a86cc548e0da6636
4
- data.tar.gz: bed0f9307f53602e2956369b5419e3173410d8bd
3
+ metadata.gz: d4b03db81cb7465b262dce0c4c8e33a14b5e290b
4
+ data.tar.gz: 42c08437e1b5f0d8452f2f2504666d6ce83006a7
5
5
  SHA512:
6
- metadata.gz: e765cd79b44de76a883867a81718e9c7b4ab4834c0ae97d59faa57728bea4e1888bc97d8c993edd6103ea6c5da1786ca33b58f18f532c5eb04c3b6e518f95a2f
7
- data.tar.gz: e62f777a303bae1fee4810bc1a1133ef2ca3d12b212ab4932666605e822d57f3ebcaf0ced16433c1b9894e43a286bd824edf30a210f24ab0a764a706420429d4
6
+ metadata.gz: 6de4243e12d2ec8d0c0c62a68a21fd9f1bef9f5a40caebe494687656ab5714d1d88e56ff7aa091796c52a57321e74e6c287ddab02e3968a0029e0203ff3ea47a
7
+ data.tar.gz: 910e524b426859dae7e5996bf25148aedf2eebea36decbc602965b483d8cf010ff224e998707c6d35bac7f80036ff0f609ef6dfd88410bf562700d967ad30b34
data/Gemfile CHANGED
@@ -29,4 +29,5 @@ group :development do
29
29
  gem 'activerecord', '~> 4.0', '>= 4.0.0'
30
30
  gem 'protected_attributes', '~> 1.0', '>= 1.0.8'
31
31
  gem 'pry'
32
+ gem 'rake-compiler', '~> 0.9', '>= 0.9.5'
32
33
  end
data/Gemfile.lock CHANGED
@@ -88,6 +88,8 @@ GEM
88
88
  slop (~> 3.4)
89
89
  rack (1.5.2)
90
90
  rake (10.3.2)
91
+ rake-compiler (0.9.5)
92
+ rake
91
93
  rdoc (4.1.1)
92
94
  json (~> 1.4)
93
95
  rest-client (1.7.2)
@@ -139,6 +141,7 @@ DEPENDENCIES
139
141
  mysql2 (~> 0.3, >= 0.3.17)
140
142
  protected_attributes (~> 1.0, >= 1.0.8)
141
143
  pry
144
+ rake-compiler (~> 0.9, >= 0.9.5)
142
145
  rest-client (~> 1.6, >= 1.6.7)
143
146
  rspec (~> 3.0)
144
147
  ruby-prof (~> 0.15, >= 0.15.1)
data/Rakefile CHANGED
@@ -32,3 +32,15 @@ RSpec::Core::RakeTask.new(:spec) do |t|
32
32
  end
33
33
 
34
34
  task :default => :spec
35
+
36
+ require 'rake/extensiontask'
37
+
38
+ Rake::ExtensionTask.new "dump_parser_ext" do |ext|
39
+ ext.ext_dir = "ext/flydata/parser/mysql"
40
+ ext.lib_dir = "lib/flydata/parser/mysql"
41
+ end
42
+
43
+ Rake::ExtensionTask.new "json_ext" do |ext|
44
+ ext.ext_dir = "ext/flydata/json"
45
+ ext.lib_dir = "lib/flydata/json"
46
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.12
1
+ 0.5.13
@@ -0,0 +1,13 @@
1
+ #ifndef __FLYDATA_H
2
+ #define __FLYDATA_H
3
+
4
+ #define __F(f) (reinterpret_cast<VALUE (*)(...)>(f))
5
+
6
+ #ifdef DEBUG
7
+ #define debug_print(fmt, ...) \
8
+ do { if (DEBUG) fprintf(stderr, fmt, __VA_ARGS__); } while (0)
9
+ #else
10
+ #define debug_print
11
+ #endif
12
+
13
+ #endif // __FLYDATA_H
@@ -0,0 +1,3 @@
1
+ require "mkmf"
2
+
3
+ create_makefile "flydata/json/json_ext"
@@ -0,0 +1,137 @@
1
+ #include <sstream>
2
+ #include <ruby.h>
3
+ #include <ruby/encoding.h>
4
+ #include "../flydata.h"
5
+
6
+ extern "C" {
7
+ #ifdef _WIN32
8
+ _declspec(dllexport)
9
+ #endif
10
+ void Init_json_ext();
11
+ }
12
+
13
+ inline void add_json_value(const char* buf, long buf_len, bool quote, std::stringstream& ss)
14
+ {
15
+ if (quote)
16
+ {
17
+ ss.put('\"');
18
+ }
19
+ const char* ptr = 0;
20
+ long len = 0;
21
+ const char* esc_str = 0;
22
+ for (long i = 0; i < buf_len; i++) {
23
+ if (!ptr) { ptr = buf + i; len = 0; }
24
+ switch (buf[i])
25
+ {
26
+ case '\"':
27
+ esc_str = "\\\"";
28
+ case '\\':
29
+ esc_str = "\\\\";
30
+ case '/':
31
+ esc_str = "\\/";
32
+ case '\b':
33
+ esc_str = "\\b";
34
+ case '\f':
35
+ esc_str = "\\f";
36
+ case '\n':
37
+ esc_str = "\\n";
38
+ case '\r':
39
+ esc_str = "\\r";
40
+ case '\t':
41
+ esc_str = "\\t";
42
+
43
+ if (len > 0)
44
+ {
45
+ ss.write(ptr, len);
46
+ }
47
+ ss.write(esc_str, 2);
48
+ ptr = 0; len = 0;
49
+ break;
50
+ default:
51
+ len++;
52
+ break;
53
+ }
54
+ }
55
+ if (len > 0) {
56
+ ss.write(ptr, len);
57
+ }
58
+
59
+ if (quote)
60
+ {
61
+ ss.put('\"');
62
+ }
63
+ }
64
+
65
+ inline void add_json_value(VALUE value, std::stringstream& ss)
66
+ {
67
+ switch(TYPE(value))
68
+ {
69
+ case T_STRING:
70
+ add_json_value(RSTRING_PTR(value), RSTRING_LEN(value), true, ss);
71
+ break;
72
+ case T_NIL:
73
+ add_json_value("null", 4, false, ss);
74
+ break;
75
+ case T_TRUE:
76
+ add_json_value("true", 4, false, ss);
77
+ break;
78
+ case T_FALSE:
79
+ add_json_value("false", 5, false, ss);
80
+ break;
81
+ default:
82
+ VALUE v = rb_funcall(value, rb_intern("to_s"), 0);
83
+ add_json_value(RSTRING_PTR(v), RSTRING_LEN(v), true, ss);
84
+ break;
85
+ }
86
+ }
87
+
88
+ inline void add_kv_pair(VALUE key, VALUE value, std::stringstream& ss)
89
+ {
90
+ if (TYPE(key) != T_STRING)
91
+ {
92
+ key = rb_funcall(key, rb_intern("to_s"), 0);
93
+ }
94
+ add_json_value(key, ss);
95
+ ss.put(':');
96
+ add_json_value(value, ss);
97
+ }
98
+
99
+ static VALUE rb_json_generate_kv_pairs(VALUE self, VALUE key_ary, VALUE value_ary)
100
+ {
101
+ long key_len = RARRAY_LEN(key_ary);
102
+ long value_len = RARRAY_LEN(value_ary);
103
+
104
+ if (key_len != value_len)
105
+ {
106
+ rb_raise(rb_eArgError, "length of arrays must match");
107
+ }
108
+
109
+ std::stringstream ss;
110
+
111
+ ss << "{";
112
+
113
+ for (long i = 0; i < key_len; i++)
114
+ {
115
+ if (i > 0) { ss << ","; }
116
+
117
+ VALUE key = rb_ary_entry(key_ary, i);
118
+ VALUE value = rb_ary_entry(value_ary, i);
119
+
120
+ add_kv_pair(key, value, ss);
121
+ }
122
+ ss << "}";
123
+
124
+ std::string str = ss.str();
125
+ VALUE json = rb_str_new(str.data(), str.size());
126
+ int enc = rb_enc_find_index("UTF-8");
127
+ rb_enc_associate_index(json, enc);
128
+
129
+ return json;
130
+ }
131
+
132
+ void Init_json_ext()
133
+ {
134
+ VALUE mJSON = rb_define_module("JSON");
135
+
136
+ rb_define_singleton_method(mJSON, "generate_kv_pairs", __F(&rb_json_generate_kv_pairs), 2);
137
+ }
@@ -0,0 +1 @@
1
+ Makefile
@@ -0,0 +1,106 @@
1
+ //#define DEBUG 1
2
+
3
+ #include <iostream>
4
+ #include <ruby.h>
5
+ #include <ruby/encoding.h>
6
+ #include "sql_parser.h"
7
+ #include "../../flydata.h"
8
+
9
+ extern "C" {
10
+ #ifdef _WIN32
11
+ _declspec(dllexport)
12
+ #endif
13
+ void Init_dump_parser_ext();
14
+ }
15
+
16
+ class InsertParserCallbackHandler : public ParserCallbackHandler
17
+ {
18
+ VALUE m_rows;
19
+ VALUE m_row;
20
+ VALUE m_value;
21
+
22
+ public:
23
+
24
+ InsertParserCallbackHandler() : ParserCallbackHandler(), m_rows(rb_ary_new()), m_row(rb_ary_new()), m_value(Qnil)
25
+ {
26
+ }
27
+
28
+ void value_callback(const char* str, long len, bool end_value)
29
+ {
30
+ if (m_value == Qnil)
31
+ {
32
+ if (str || len > 0)
33
+ {
34
+ m_value = rb_str_new(str, len);
35
+ int enc = rb_enc_find_index("UTF-8");
36
+ rb_enc_associate_index(m_value, enc);
37
+ debug_print("new value:%s\n", StringValueCStr(m_value));
38
+ }
39
+ else
40
+ {
41
+ m_value = Qnil;
42
+ debug_print("new value:%s\n", "nil");
43
+ }
44
+ }
45
+ else
46
+ {
47
+ rb_str_cat(m_value, str, len);
48
+ debug_print("value appended:%s\n", StringValueCStr(m_value));
49
+ }
50
+
51
+ if (end_value)
52
+ {
53
+ rb_ary_push(m_row, m_value);
54
+ debug_print("value committed:%s\n",
55
+ m_value == Qnil ? "nil" : StringValueCStr(m_value));
56
+ m_value = Qnil;
57
+ }
58
+ }
59
+
60
+ void row_end_callback()
61
+ {
62
+ if (m_row)
63
+ {
64
+ rb_ary_push(m_rows, m_row);
65
+ debug_print("row pushed\n", 0);
66
+ m_row = rb_ary_new();
67
+ }
68
+ }
69
+
70
+ VALUE rows()
71
+ {
72
+ return m_rows;
73
+ }
74
+ };
75
+
76
+ static VALUE rb_insert_parser_parse2(VALUE self, VALUE sql)
77
+ {
78
+ InsertParserCallbackHandler ch;
79
+
80
+ long error_at = -1;
81
+ if (sql != Qnil)
82
+ {
83
+ StringValue(sql);
84
+ error_at = parse_insert_query(RSTRING_PTR(sql), RSTRING_LEN(sql), ch);
85
+ }
86
+
87
+ if (error_at > -1) {
88
+ VALUE mFlydata = rb_define_module("Flydata");
89
+ VALUE eAgentError = rb_define_class_under(mFlydata, "AgentError", rb_eStandardError);
90
+ VALUE eDumpParseError = rb_define_class_under(mFlydata, "DumpParseError", eAgentError);
91
+ rb_raise(eDumpParseError, "Parse error at %ld", error_at);
92
+ }
93
+
94
+ return ch.rows();
95
+ }
96
+
97
+ void Init_dump_parser_ext()
98
+ {
99
+ VALUE mFlydata = rb_define_module("Flydata");
100
+ VALUE mParser = rb_define_module_under(mFlydata, "Parser");
101
+ VALUE mMysql = rb_define_module_under(mParser, "Mysql");
102
+ VALUE cMysqlDumpParser = rb_define_class_under(mMysql, "MysqlDumpParser", rb_cObject);
103
+ VALUE cInsertParser = rb_define_class_under(cMysqlDumpParser, "InsertParser", rb_cObject);
104
+
105
+ rb_define_private_method(cInsertParser, "_parse2", __F(&rb_insert_parser_parse2), 1);
106
+ }
@@ -0,0 +1,3 @@
1
+ require "mkmf"
2
+
3
+ create_makefile "flydata/parser/mysql/dump_parser_ext"
@@ -0,0 +1,121 @@
1
+ start:
2
+ "(" => :value
3
+ else => :start
4
+
5
+ value:
6
+ " ", "\t", "\n", "," => :value
7
+ "'" => :first_char
8
+ "0" => (mark), :first_zero
9
+ [1-9-] => (mark), :number
10
+ "N" => :null_n
11
+ ")" => (row_end_callback), :start
12
+ else => :error
13
+
14
+ first_zero:
15
+ "0" => (mark), :leading_zero
16
+ [1-9] => (mark), :number
17
+ "." => :number
18
+ [xX] => :hex_blob
19
+ "," => (value_callback, :end_value)(mark reset), :value
20
+ ")" => (value_callback, :end_value)(mark reset)(row_end_callback), :start
21
+ else => :error
22
+
23
+ leading_zero:
24
+ "0" => (mark), :leading_zero
25
+ [1-9] => (mark), :number
26
+ "." => :number
27
+ "," => (value_callback, :end_value)(mark reset), :value
28
+ ")" => (value_callback, :end_value)(mark reset)(row_end_callback), :start
29
+ else => :error
30
+
31
+ number:
32
+ [0-9.] => :number
33
+ "," => (value_callback, :end_value)(mark reset), :value
34
+ ")" => (value_callback, :end_value)(mark reset)(row_end_callback), :start
35
+ else => :error
36
+
37
+ null_n:
38
+ "U" => :null_u
39
+ else => :error
40
+
41
+ null_u:
42
+ "L" => :null_l1
43
+ else => :error
44
+
45
+ null_l1:
46
+ "L" => :null_l2
47
+ else => :error
48
+
49
+ null_l2:
50
+ "," => (value_callback 0, :end_value)(mark_reset), :value # 0 is NULL pointer
51
+ ")" => (value_callback 0, :end_value)(mark_reset)(row_end_callback), :start # 0 is NULL pointer
52
+ else => :error
53
+
54
+ hex_blob:
55
+ [0-9a-fA-F] => :hex_blob_number
56
+ else => :error
57
+
58
+ hex_blob_number:
59
+ [0-9a-fA-F] => :hex_blob_number
60
+ "," => (value_callback, :end_value)(mark_reset), :value
61
+ ")" => (value_callback, :end_value)(mark_reset)(row_end_callback), :start
62
+ else => :error
63
+
64
+ first_char:
65
+ "\\" => (mark), :escape
66
+ "'" => (mark)(value_callback, :end_value)(mark_reset), :value
67
+ mask 110xxxxx => (mark)(temp_mark), :utf8_2_firstbyte
68
+ mask 1110xxxx => (mark)(temp_mark), :utf8_3_firstbyte
69
+ mask 11110xxx => (mark)(temp_mark), :utf8_4_firstbyte
70
+ else => (mark), :following_char
71
+
72
+ utf8_2_firstbyte:
73
+ mask 10xxxxxx => (temp_mark reset), :following_char
74
+ else (value_callback mark...temp_mark)(mark reset)(value_callback "\xc2\xbf\xc2\xbf")(temp_mark reset), :first_char
75
+
76
+ utf8_3_firstbyte:
77
+ mask 10xxxxxx => :utf8_3_secondbyte
78
+ else => :utf8_3_error_secondbyte
79
+
80
+ utf8_3_secondbyte:
81
+ mask 10xxxxxx => (temp_mark reset), :following_char
82
+ else (value_callback mark...temp_mark)(mark reset)(value_callback "\xc2\xbf\xc2\xbf\xc2\xbf")(temp_mark reset), :first_char
83
+
84
+ utf8_3_error_secondbyte:
85
+ any char => (value_callback mark...temp_mark)(mark reset)(value_callback "\xc2\xbf\xc2\xbf\xc2\xbf")(temp_mark reset), :first_char
86
+
87
+ utf8_4_firstbyte:
88
+ mask 10xxxxxx => :utf8_4_secondbyte
89
+ else => :utf8_4_error_secondbyte
90
+
91
+ utf8_4_secondbyte:
92
+ mask 10xxxxxx => :utf_4_thirdbyte
93
+ else => :utf8_4_error_thirdbyte
94
+
95
+ utf8_4_error_secondbyte:
96
+ any_char => :utf8_4_error_thirdbyte
97
+
98
+ utf8_4_thirdbyte:
99
+ mask 10xxxxxx => (temp_mark reset), :following_char
100
+ else (value_callback mark...temp_mark)(mark reset)(value_callback "\xc2\xbf\xc2\xbf\xc2\xbf\xc2\xbf")(temp_mark reset), :first_char
101
+
102
+ utf8_4_error_thirdbyte:
103
+ any char => (value_callback mark...temp_mark)(mark reset)(value_callback "\xc2\xbf\xc2\xbf\xc2\xbf\xc2\xbf")(temp_mark reset), :first_char
104
+
105
+ following_char:
106
+ "\\" => (value_callback)(mark), :escape
107
+ "'" => (value_callback, :end_value)(mark_reset), :value
108
+ mask 110xxxxx => (temp_mark), :utf8_2_firstbyte
109
+ mask 1110xxxx => (temp_mark), :utf8_3_firstbyte
110
+ mask 11110xxx => (temp_mark), :utf8_4_firstbyte
111
+ else => :following_char
112
+
113
+ escape:
114
+ "\\" => (value_callback "\\")(mark_reset), :first_char
115
+ "'" => (value_callback "'")(mark_reset), :first_char
116
+ '"' => (value_callback '"')(mark_reset), :first_char
117
+ "n" => (value_callback "\n")(mark_reset), :first_char
118
+ "r" => (value_callback "\r")(mark_reset), :first_char
119
+ "0" => (value_callback "\0")(mark_reset), :first_char
120
+ "Z" => (value_callback "\Z")(mark_reset), :first_char
121
+ else => :following_char