gda 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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