gda 1.0.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,9 @@
1
+ #ifndef _RUBY_GDA_NODES
2
+ #define _RUBY_GDA_NODES
3
+
4
+ void Init_gda_nodes();
5
+
6
+ VALUE WrapAnyPart(VALUE stmt, GdaSqlAnyPart *part);
7
+
8
+ #endif
9
+
@@ -0,0 +1,61 @@
1
+ #include <gda.h>
2
+
3
+ VALUE cProvider;
4
+
5
+ static VALUE name(VALUE self)
6
+ {
7
+ GdaServerProvider * pr;
8
+ Data_Get_Struct(self, GdaServerProvider, pr);
9
+
10
+ return rb_tainted_str_new2(gda_server_provider_get_name(pr));
11
+ }
12
+
13
+ static VALUE find(VALUE klass, VALUE string)
14
+ {
15
+ GdaServerProvider * pr;
16
+ GError * error = NULL;
17
+
18
+ pr = gda_config_get_provider(StringValuePtr(string), &error);
19
+
20
+ if (pr)
21
+ return Data_Wrap_Struct(klass, NULL, NULL, pr);
22
+ else {
23
+ /* FIXME: should actually raise an error here. */
24
+ g_error_free(error);
25
+ return Qnil;
26
+ }
27
+ }
28
+
29
+ static VALUE parser(VALUE self)
30
+ {
31
+ GdaSqlParser * parser;
32
+ GdaServerProvider * pr;
33
+
34
+ Data_Get_Struct(self, GdaServerProvider, pr);
35
+
36
+ parser = gda_server_provider_create_parser(pr, NULL);
37
+
38
+ if (!parser)
39
+ rb_raise(rb_eRuntimeError, "zomglol");
40
+
41
+ return Data_Wrap_Struct(cParser, NULL, g_object_unref, parser);
42
+ }
43
+
44
+ static VALUE quote_str(VALUE self, VALUE str)
45
+ {
46
+ GdaServerProvider * pr;
47
+
48
+ Data_Get_Struct(self, GdaServerProvider, pr);
49
+ return rb_str_new2(gda_sql_identifier_quote(StringValuePtr(str), NULL, pr, TRUE, TRUE));
50
+ }
51
+
52
+ void Init_gda_provider()
53
+ {
54
+ cProvider = rb_define_class_under(mSQL, "Provider", rb_cObject);
55
+ rb_define_singleton_method(cProvider, "find", find, 1);
56
+ rb_define_method(cProvider, "name", name, 0);
57
+ rb_define_method(cProvider, "parser", parser, 0);
58
+ rb_define_method(cProvider, "quote", quote_str, 1);
59
+ }
60
+
61
+ /* vim: set noet sws=4 sw=4: */
@@ -0,0 +1,7 @@
1
+ #ifndef _RUBY_GDA_PROVIDER
2
+ #define _RUBY_GDA_PROVIDER
3
+
4
+ void Init_gda_provider();
5
+
6
+ #endif
7
+
@@ -0,0 +1,58 @@
1
+ #include <gda.h>
2
+
3
+ VALUE cStatement;
4
+ VALUE cStructure;
5
+
6
+ static VALUE serialize(VALUE self)
7
+ {
8
+ GdaStatement * stmt;
9
+ gchar * string;
10
+
11
+ Data_Get_Struct(self, GdaStatement, stmt);
12
+
13
+ string = gda_statement_serialize(stmt);
14
+ return rb_str_new2(string);
15
+ }
16
+
17
+ static VALUE ast(VALUE self)
18
+ {
19
+ GdaSqlStatement * sqlst;
20
+
21
+ Data_Get_Struct(self, GdaSqlStatement, sqlst);
22
+
23
+ return WrapAnyPart(self, GDA_SQL_ANY_PART(sqlst->contents));
24
+ }
25
+
26
+ static VALUE sql(VALUE self)
27
+ {
28
+ GdaSqlStatement * sqlst;
29
+
30
+ Data_Get_Struct(self, GdaSqlStatement, sqlst);
31
+
32
+ return rb_str_new2(sqlst->sql);
33
+ }
34
+
35
+ static VALUE structure(VALUE self)
36
+ {
37
+ GdaStatement * stmt;
38
+ GdaSqlStatement * sqlst;
39
+
40
+ Data_Get_Struct(self, GdaStatement, stmt);
41
+
42
+ g_object_get(G_OBJECT(stmt), "structure", &sqlst, NULL);
43
+
44
+ return Data_Wrap_Struct(cStructure, NULL, gda_sql_statement_free, sqlst);
45
+ }
46
+
47
+ void Init_gda_statement()
48
+ {
49
+ cStatement = rb_define_class_under(mSQL, "Statement", rb_cObject);
50
+ cStructure = rb_define_class_under(mSQL, "Structure", rb_cObject);
51
+
52
+ rb_define_method(cStatement, "serialize", serialize, 0);
53
+ rb_define_method(cStatement, "structure", structure, 0);
54
+ rb_define_method(cStructure, "ast", ast, 0);
55
+ rb_define_method(cStructure, "sql", sql, 0);
56
+ }
57
+
58
+ /* vim: set noet sws=4 sw=4: */
@@ -0,0 +1,6 @@
1
+ #ifndef _RUBY_GDA_STATEMENT
2
+ #define _RUBY_GDA_STATEMENT
3
+
4
+ void Init_gda_statement();
5
+
6
+ #endif
@@ -0,0 +1,39 @@
1
+ require 'gda.so'
2
+ require 'gda/visitors/each'
3
+ require 'gda/visitors/dot'
4
+ require 'gda/visitors/max_depth'
5
+
6
+ module GDA
7
+ VERSION = '1.0.0'
8
+
9
+ module SQL
10
+ class Statement
11
+ def ast
12
+ structure.ast
13
+ end
14
+
15
+ def sql
16
+ structure.sql
17
+ end
18
+ end
19
+ end
20
+
21
+ module Nodes
22
+ class Node
23
+ include Enumerable
24
+
25
+ def each &block
26
+ Visitors::Each.new(block).accept self
27
+ end
28
+
29
+ def to_dot
30
+ viz = Visitors::Dot.new
31
+ viz.accept self
32
+ end
33
+
34
+ def max_depth
35
+ Visitors::MaxDepth.new.accept(self)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,188 @@
1
+ require 'gda/visitors/visitor'
2
+ require 'erb'
3
+ require 'stringio'
4
+
5
+ module GDA
6
+ module Visitors
7
+ class Dot < GDA::Visitors::Visitor
8
+ attr_reader :stack
9
+
10
+ def initialize io = StringIO.new
11
+ @stack = []
12
+ @buffer = io
13
+ end
14
+
15
+ HEADER = "digraph G { graph [rankdir = \"TB\"];"
16
+ FOOTER = "}"
17
+
18
+ def accept node
19
+ puts HEADER
20
+ super
21
+ puts FOOTER
22
+ @buffer.string
23
+ end
24
+
25
+ private
26
+
27
+ def puts str
28
+ @buffer.puts str
29
+ end
30
+
31
+ def printf *args
32
+ @buffer.printf(*args)
33
+ end
34
+
35
+ NODE = ERB.new <<-eoerb
36
+ node<%= node.object_id %> [shape="plaintext" label=<
37
+ <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
38
+ <TR><TD COLSPAN="2"><%= node.class %></TD></TR>
39
+ <% attrs.each do |attr| %>
40
+ <% next if node.send(attr).nil? %>
41
+ <TR><TD><%= ERB::Util.h attr %></TD><TD><%= ERB::Util.h node.send(attr) %></TD></TR>
42
+ <% end %>
43
+ </TABLE>>];
44
+ eoerb
45
+
46
+ LIST = ERB.new <<-eoerb
47
+ node<%= node.object_id %> [shape="invhouse", color=gray, fontcolor=gray, label=list];
48
+ eoerb
49
+
50
+ def add_node node, attrs = []
51
+ puts NODE.result binding
52
+ link_node node
53
+ end
54
+
55
+ FMT = "node%d -> node%d [ label = \"%s\" ];\n"
56
+
57
+ def link_node node
58
+ return if stack.empty?
59
+ printf FMT, stack.last.first.object_id, node.object_id, stack.last.last
60
+ end
61
+
62
+ def add_list node
63
+ puts LIST.result binding
64
+ link_node node
65
+ end
66
+
67
+ def visit_edge node, edge
68
+ stack.push [node, edge]
69
+ visit node.send edge
70
+ stack.pop
71
+ end
72
+
73
+ def visit_Array node
74
+ return if node.empty?
75
+
76
+ add_list node
77
+ node.each_with_index { |n, i|
78
+ stack.push [node, i]
79
+ visit n
80
+ stack.pop
81
+ }
82
+ end
83
+
84
+ def visit_GDA_Nodes_Insert node
85
+ add_node node, [:on_conflict]
86
+ visit_edge node, :table
87
+ visit_edge node, :fields_list
88
+ visit_edge node, :values_list
89
+ end
90
+
91
+ def visit_GDA_Nodes_Update node
92
+ add_node node, [:on_conflict]
93
+ visit_edge node, :table
94
+ visit_edge node, :fields_list
95
+ visit_edge node, :expr_list
96
+ visit_edge node, :cond
97
+ end
98
+
99
+ def visit_GDA_Nodes_Delete node
100
+ add_node node
101
+ visit_edge node, :table
102
+ visit_edge node, :cond
103
+ end
104
+
105
+ def visit_GDA_Nodes_Select node
106
+ add_node node
107
+ visit_edge node, :distinct_expr
108
+ visit_edge node, :expr_list
109
+ visit_edge node, :from
110
+ visit_edge node, :where_cond
111
+ visit_edge node, :group_by
112
+ visit_edge node, :having_cond
113
+ visit_edge node, :order_by
114
+ visit_edge node, :limit_count
115
+ visit_edge node, :limit_offset
116
+ end
117
+
118
+ def visit_GDA_Nodes_Table node
119
+ add_node node, [:table_name]
120
+ end
121
+
122
+ def visit_GDA_Nodes_SelectField node
123
+ add_node node, [:field_name, :table_name, :as]
124
+ visit_edge node, :expr
125
+ end
126
+
127
+ def visit_GDA_Nodes_Expr node
128
+ add_node node, [:value, :cast_as]
129
+ visit_edge node, :func
130
+ visit_edge node, :cond
131
+ visit_edge node, :select
132
+ visit_edge node, :case_s
133
+ visit_edge node, :param_spec
134
+ end
135
+
136
+ def visit_GDA_Nodes_Field node
137
+ add_node node, [:field_name]
138
+ end
139
+
140
+ def visit_GDA_Nodes_Operation node
141
+ add_node node, [:operator]
142
+ visit_edge node, :operands
143
+ end
144
+
145
+ def visit_GDA_Nodes_From node
146
+ add_node node
147
+ visit_edge node, :targets
148
+ visit_edge node, :joins
149
+ end
150
+
151
+ def visit_GDA_Nodes_Target node
152
+ add_node node, [:table_name, :as]
153
+ visit_edge node, :expr
154
+ end
155
+
156
+ def visit_GDA_Nodes_Function node
157
+ add_node node, [:function_name]
158
+ visit_edge node, :args_list
159
+ end
160
+
161
+ def visit_GDA_Nodes_Order node
162
+ add_node node, [:asc, :collation_name]
163
+ visit_edge node, :expr
164
+ end
165
+
166
+ def visit_GDA_Nodes_Unknown node
167
+ add_node node
168
+ visit_edge node, :expressions
169
+ end
170
+
171
+ def visit_GDA_Nodes_Join node
172
+ add_node node, [:join_type, :position]
173
+ visit_edge node, :expr
174
+ visit_edge node, :use
175
+ end
176
+
177
+ def visit_GDA_Nodes_Savepoint node
178
+ add_node node, [:__type__, :isolation_level, :trans_mode, :trans_name]
179
+ end
180
+
181
+ alias visit_GDA_Nodes_RollbackSavepoint visit_GDA_Nodes_Savepoint
182
+ alias visit_GDA_Nodes_DeleteSavepoint visit_GDA_Nodes_Savepoint
183
+ alias visit_GDA_Nodes_Rollback visit_GDA_Nodes_Savepoint
184
+ alias visit_GDA_Nodes_Commit visit_GDA_Nodes_Savepoint
185
+ alias visit_GDA_Nodes_Begin visit_GDA_Nodes_Savepoint
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,18 @@
1
+ require 'gda/visitors/visitor'
2
+
3
+ module GDA
4
+ module Visitors
5
+ class Each < Visitor
6
+ def initialize block
7
+ @block = block
8
+ end
9
+
10
+ def visit node
11
+ super
12
+ unless node.nil? || Array === node
13
+ @block.call node
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ require 'gda/visitors/visitor'
2
+
3
+ module GDA
4
+ module Visitors
5
+ class MaxDepth < Visitor
6
+ def initialize
7
+ @max = 0
8
+ @current = 0
9
+ super
10
+ end
11
+
12
+ def accept node
13
+ super
14
+ @max
15
+ end
16
+
17
+ private
18
+
19
+ def visit node
20
+ return super if node.nil?
21
+
22
+ @current += 1
23
+ super
24
+ @max = [@max, @current].max
25
+ @current -= 1
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,129 @@
1
+ module GDA
2
+ module Visitors
3
+ class Visitor
4
+ def accept node
5
+ visit node
6
+ end
7
+
8
+ private
9
+
10
+ def visit node
11
+ return unless node
12
+
13
+ method = METHOD_CACHE.fetch(node.class) { |k|
14
+ "visit_" + k.name.split('::').join('_')
15
+ }
16
+
17
+ send method, node
18
+ end
19
+
20
+ def visit_Array node
21
+ node.each { |n| visit n }
22
+ end
23
+
24
+ def visit_GDA_Nodes_Select node
25
+ visit node.distinct_expr
26
+ visit node.expr_list
27
+ visit node.from
28
+ visit node.where_cond
29
+ visit node.group_by
30
+ visit node.having_cond
31
+ visit node.order_by
32
+ visit node.limit_count
33
+ visit node.limit_offset
34
+ end
35
+
36
+ def visit_GDA_Nodes_Insert node
37
+ visit node.table
38
+ visit node.fields_list
39
+ visit node.values_list
40
+ visit node.select
41
+ end
42
+
43
+ def visit_GDA_Nodes_Update node
44
+ visit node.table
45
+ visit node.fields_list
46
+ visit node.expr_list
47
+ visit node.cond
48
+ end
49
+
50
+ def visit_GDA_Nodes_Join node
51
+ visit node.expr
52
+ visit node.use
53
+ end
54
+
55
+ def visit_GDA_Nodes_Delete node
56
+ visit node.table
57
+ visit node.cond
58
+ end
59
+
60
+ def visit_GDA_Nodes_SelectField node
61
+ visit node.expr
62
+ end
63
+
64
+ def visit_GDA_Nodes_Expr node
65
+ visit node.func
66
+ visit node.cond
67
+ visit node.select
68
+ visit node.case_s
69
+ visit node.param_spec
70
+ end
71
+
72
+ def visit_GDA_Nodes_From node
73
+ visit node.targets
74
+ visit node.joins
75
+ end
76
+
77
+ def visit_GDA_Nodes_Target node
78
+ visit node.expr
79
+ end
80
+
81
+ def visit_GDA_Nodes_Operation node
82
+ visit node.operands
83
+ end
84
+
85
+ def visit_GDA_Nodes_Function node
86
+ visit node.args_list
87
+ end
88
+
89
+ def visit_GDA_Nodes_Order node
90
+ visit node.expr
91
+ end
92
+
93
+ def visit_GDA_Nodes_Unknown node
94
+ visit node.expressions
95
+ end
96
+
97
+ ## Terminal nodes
98
+ def visit_GDA_Nodes_Table node
99
+ end
100
+
101
+ def visit_GDA_Nodes_Field node
102
+ end
103
+
104
+ def visit_GDA_Nodes_Savepoint node
105
+ end
106
+
107
+ def visit_GDA_Nodes_RollbackSavepoint node
108
+ end
109
+
110
+ def visit_GDA_Nodes_Begin node
111
+ end
112
+
113
+ def visit_GDA_Nodes_DeleteSavepoint node
114
+ end
115
+
116
+ def visit_GDA_Nodes_Rollback node
117
+ end
118
+
119
+ def visit_GDA_Nodes_Commit node
120
+ end
121
+
122
+ METHOD_CACHE = {}
123
+ private_instance_methods.grep(/^visit_(.*)$/) do |method|
124
+ k = $1.split('_').inject(Object) { |klass,c| klass.const_get c }
125
+ METHOD_CACHE[k] = method
126
+ end
127
+ end
128
+ end
129
+ end