sqlconstructor 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.
Files changed (80) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE.md +16 -0
  3. data/README.md +161 -0
  4. data/Rakefile +11 -0
  5. data/doc/Object.html +267 -0
  6. data/doc/Rakefile.html +150 -0
  7. data/doc/SQLAliasedList.html +717 -0
  8. data/doc/SQLColumn.html +326 -0
  9. data/doc/SQLCondList.html +318 -0
  10. data/doc/SQLConditional.html +1082 -0
  11. data/doc/SQLConditional/BasicCond.html +325 -0
  12. data/doc/SQLConstructor.html +763 -0
  13. data/doc/SQLConstructor/BasicDelete.html +383 -0
  14. data/doc/SQLConstructor/BasicDelete_mysql.html +368 -0
  15. data/doc/SQLConstructor/BasicInsert.html +339 -0
  16. data/doc/SQLConstructor/BasicInsert_mysql.html +325 -0
  17. data/doc/SQLConstructor/BasicJoin.html +408 -0
  18. data/doc/SQLConstructor/BasicJoin_mysql.html +439 -0
  19. data/doc/SQLConstructor/BasicSelect.html +554 -0
  20. data/doc/SQLConstructor/BasicSelect_example.html +288 -0
  21. data/doc/SQLConstructor/BasicSelect_mysql.html +466 -0
  22. data/doc/SQLConstructor/BasicUnion.html +396 -0
  23. data/doc/SQLConstructor/BasicUpdate.html +409 -0
  24. data/doc/SQLConstructor/BasicUpdate_mysql.html +310 -0
  25. data/doc/SQLConstructor/GenericQuery.html +797 -0
  26. data/doc/SQLConstructor/QAttr.html +398 -0
  27. data/doc/SQLConstructorTest.html +603 -0
  28. data/doc/SQLExporter.html +382 -0
  29. data/doc/SQLExporter/Exporter_generic.html +413 -0
  30. data/doc/SQLExporter/Exporter_mysql.html +395 -0
  31. data/doc/SQLObject.html +525 -0
  32. data/doc/SQLValList.html +322 -0
  33. data/doc/SQLValue.html +375 -0
  34. data/doc/created.rid +12 -0
  35. data/doc/images/brick.png +0 -0
  36. data/doc/images/brick_link.png +0 -0
  37. data/doc/images/bug.png +0 -0
  38. data/doc/images/bullet_black.png +0 -0
  39. data/doc/images/bullet_toggle_minus.png +0 -0
  40. data/doc/images/bullet_toggle_plus.png +0 -0
  41. data/doc/images/date.png +0 -0
  42. data/doc/images/find.png +0 -0
  43. data/doc/images/loadingAnimation.gif +0 -0
  44. data/doc/images/macFFBgHack.png +0 -0
  45. data/doc/images/package.png +0 -0
  46. data/doc/images/page_green.png +0 -0
  47. data/doc/images/page_white_text.png +0 -0
  48. data/doc/images/page_white_width.png +0 -0
  49. data/doc/images/plugin.png +0 -0
  50. data/doc/images/ruby.png +0 -0
  51. data/doc/images/tag_green.png +0 -0
  52. data/doc/images/wrench.png +0 -0
  53. data/doc/images/wrench_orange.png +0 -0
  54. data/doc/images/zoom.png +0 -0
  55. data/doc/index.html +356 -0
  56. data/doc/js/darkfish.js +118 -0
  57. data/doc/js/jquery.js +32 -0
  58. data/doc/js/quicksearch.js +114 -0
  59. data/doc/js/thickbox-compressed.js +10 -0
  60. data/doc/lib/dialects/example-constructor_rb.html +52 -0
  61. data/doc/lib/dialects/mysql-constructor_rb.html +52 -0
  62. data/doc/lib/dialects/mysql-exporter_rb.html +54 -0
  63. data/doc/lib/sqlconditional_rb.html +64 -0
  64. data/doc/lib/sqlconstructor_rb.html +52 -0
  65. data/doc/lib/sqlerrors_rb.html +54 -0
  66. data/doc/lib/sqlexporter_rb.html +55 -0
  67. data/doc/lib/sqlobject_rb.html +54 -0
  68. data/doc/rdoc.css +763 -0
  69. data/doc/test/queries_rb.html +56 -0
  70. data/doc/test_rb.html +52 -0
  71. data/lib/dialects/example-constructor.rb +45 -0
  72. data/lib/dialects/mysql-constructor.rb +247 -0
  73. data/lib/dialects/mysql-exporter.rb +108 -0
  74. data/lib/sqlconditional.rb +196 -0
  75. data/lib/sqlconstructor.rb +708 -0
  76. data/lib/sqlerrors.rb +15 -0
  77. data/lib/sqlexporter.rb +125 -0
  78. data/lib/sqlobject.rb +284 -0
  79. data/test/queries.rb +92 -0
  80. metadata +121 -0
@@ -0,0 +1,56 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: queries.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="../rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="../js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="../js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="../js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="../js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2014-08-28 15:20:52 +0400</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ <li>test/unit</li>
35
+
36
+ <li>sqlconstructor</li>
37
+
38
+ </ul>
39
+ </dd>
40
+
41
+
42
+
43
+ </dl>
44
+ </div>
45
+
46
+ <div id="documentation">
47
+
48
+ <div class="description">
49
+ <h2>Description</h2>
50
+
51
+ </div>
52
+
53
+ </div>
54
+ </body>
55
+ </html>
56
+
@@ -0,0 +1,52 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: test.rb [RDoc Documentation]</title>
10
+
11
+ <link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="./js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="./js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="./js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="./js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">2014-08-29 10:20:36 +0400</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ </ul>
35
+ </dd>
36
+
37
+
38
+
39
+ </dl>
40
+ </div>
41
+
42
+ <div id="documentation">
43
+
44
+ <div class="description">
45
+ <h2>Description</h2>
46
+
47
+ </div>
48
+
49
+ </div>
50
+ </body>
51
+ </html>
52
+
@@ -0,0 +1,45 @@
1
+
2
+
3
+
4
+ class SQLConstructor::BasicSelect_example < SQLConstructor::BasicSelect
5
+
6
+ # attr_reader :attr_foo
7
+
8
+
9
+ ##########################################################################
10
+ # Class constructor.
11
+ # Init any attributes here. Do not forget to call 'super'!
12
+ # _caller - the caller object
13
+ # *list - list of sources for the FROM clause
14
+ ##########################################################################
15
+ def initialize ( _caller, *list )
16
+ super
17
+ # @attr_foo = false
18
+ end
19
+
20
+
21
+ ##########################################################################
22
+ # Define your methods here.
23
+ # If your dialect supports a keyword FOO, so that you would want to
24
+ # construct something like
25
+ # SELECT a FROM t WHERE b=1 FOO 5
26
+ # you'll need to implement a foo() method here and further use it like
27
+ # SQLConstructor.new.select(:a).from('t').where.eq(:b,1).foo(5)
28
+ ##########################################################################
29
+
30
+ # def foo ( value = nil )
31
+ # @attr_foo = value
32
+ # return self
33
+ # end
34
+
35
+
36
+ #############################################################################
37
+ # You may do mostly anything here, but don't forget to call method_missing
38
+ # of the parent ( 'return super' )
39
+ #############################################################################
40
+ def method_missing ( method, *args )
41
+ return super
42
+ end
43
+
44
+ end
45
+
@@ -0,0 +1,247 @@
1
+
2
+ VALID_INDEX_HINTS = [ :use_index, :force_index, :ignore_index,
3
+ :use_key, :ignore_key, :force_key ]
4
+
5
+ ##########################################################################################
6
+ # MySQL dialect descendant of BasicSelect class
7
+ ##########################################################################################
8
+ class SQLConstructor::BasicSelect_mysql < SQLConstructor::BasicSelect
9
+
10
+ attr_reader :attr_high_priority, :attr_straight_join, :attr_sql_result_size,
11
+ :attr_sql_cache, :attr_sql_calc_found_rows, :attr_limit, :attr_group_by_with_rollup
12
+
13
+ METHODS = {
14
+ :straight_join => SQLConstructor::QAttr.new( :name => 'attr_straight_join',
15
+ :text => 'STRAIGHT_JOIN' ),
16
+ :sql_cache => SQLConstructor::QAttr.new( :name => 'attr_sql_cache', :text => 'SQL_CACHE'),
17
+ :sql_no_cache => SQLConstructor::QAttr.new( :name => 'attr_sql_cache', :text => 'SQL_NO_CACHE'),
18
+ :high_priority => SQLConstructor::QAttr.new( :name => 'attr_high_priority',:text => 'HIGH_PRIORITY' ),
19
+ :sql_calc_found_rows => SQLConstructor::QAttr.new( :name => 'attr_sql_calc_found_rows',
20
+ :text => 'SQL_CALC_FOUND_ROWS' ),
21
+ :sql_small_result => SQLConstructor::QAttr.new( :name => 'attr_sql_result_size',
22
+ :text => 'SQL_SMALL_RESULT' ),
23
+ :sql_big_result => SQLConstructor::QAttr.new( :name => 'attr_sql_result_size',
24
+ :text => 'SQL_BIG_RESULT' ),
25
+ :sql_buffer_result => SQLConstructor::QAttr.new( :name => 'attr_sql_result_size',
26
+ :text => 'SQL_BUFFER_RESULT' ),
27
+ :limit => SQLConstructor::QAttr.new( :name => 'attr_limit',
28
+ :text => 'LIMIT', :val => SQLObject ),
29
+ :group_by_with_rollup => SQLConstructor::QAttr.new( :name => 'attr_group_by_with_rollup',
30
+ :text => "WITH ROLLUP" ),
31
+ }
32
+
33
+ ##########################################################################
34
+ # Class constructor.
35
+ # _caller - the caller object
36
+ # *list - list of sources for the FROM clause
37
+ ##########################################################################
38
+ def initialize ( _caller, *list )
39
+ super
40
+ end
41
+
42
+ ##########################################################################
43
+ # Send missing methods calls to the @caller object, and also handle
44
+ # JOINs, UNIONs and INDEX hints
45
+ ##########################################################################
46
+ def method_missing ( method, *args )
47
+ # Handle all [*_]join calls:
48
+ return _addJoin( method, *args ) if method.to_s =~ /^[a-z_]*join$/
49
+ # Handle all valid *_index/*_key calls:
50
+ return _addIndexes( method, *args ) if VALID_INDEX_HINTS.include? method
51
+ super
52
+ end
53
+
54
+ #########
55
+ private
56
+ #########
57
+
58
+ ##########################################################################
59
+ # Adds a USE/FORCE/IGNORE INDEX clause for the last objects in for_vals
60
+ # argument.
61
+ ##########################################################################
62
+ def _addIndexes ( type, *list )
63
+ type = type.to_s
64
+ type.upcase!.gsub! /_/, ' '
65
+ @attr_index_hints ||= [ ]
66
+ # set the attr_index_hints for the last object in for_vals
67
+ last_ind = @attr_from.val.length - 1
68
+ @attr_index_hints[last_ind] = { :type => type, :list => SQLObject.get( list ) }
69
+ @string = nil
70
+ return self
71
+ end
72
+
73
+ end
74
+
75
+
76
+ ##########################################################################################
77
+ # MySQL dialect descendant of BasicDelete class
78
+ ##########################################################################################
79
+ class SQLConstructor::BasicDelete_mysql < SQLConstructor::BasicDelete
80
+
81
+ attr_reader :del_ignore, :del_quick, :del_low_priority, :attr_limit
82
+
83
+ METHODS = {
84
+ :low_priority => SQLConstructor::QAttr.new( :name => 'del_low_priority',
85
+ :text => 'LOW_PRIORITY' ),
86
+ :quick => SQLConstructor::QAttr.new( :name => 'del_quick', :text => 'QUICK '),
87
+ :ignore => SQLConstructor::QAttr.new( :name => 'del_ignore', :text => 'IGNORE'),
88
+ :limit => SQLConstructor::QAttr.new( :name => 'attr_limit', :text => 'LIMIT', :val => SQLObject)
89
+ }
90
+
91
+ ##########################################################################
92
+ # Class constructor.
93
+ # _caller - the caller object
94
+ ##########################################################################
95
+ def initialize ( _caller )
96
+ super
97
+ end
98
+
99
+ ##########################################################################
100
+ # Handle JOINs or send call to the parent.
101
+ ##########################################################################
102
+ def method_missing ( method, *args )
103
+ # Handle all [*_]join calls:
104
+ return _addJoin( method, *args ) if method =~ /^[a-z_]*join$/
105
+ super
106
+ end
107
+
108
+ end
109
+
110
+
111
+ ##########################################################################################
112
+ # MySQL dialect descendant of BasicInsert class
113
+ ##########################################################################################
114
+ class SQLConstructor::BasicInsert_mysql < SQLConstructor::BasicInsert
115
+
116
+ attr_reader :ins_priority, :ins_quick, :ins_ignore, :ins_on_duplicate_key_update
117
+
118
+ METHODS = {
119
+ :low_priority => SQLConstructor::QAttr.new( :name => 'ins_priority', :text => 'LOW_PRIORITY' ),
120
+ :delayed => SQLConstructor::QAttr.new( :name => 'ins_priority', :text => 'DELAYED' ),
121
+ :high_priority => SQLConstructor::QAttr.new( :name => 'ins_priority', :text => 'HIGH_PRIORITY' ),
122
+ :quick => SQLConstructor::QAttr.new( :name => 'ins_quick', :text => 'QUICK' ),
123
+ :ignore => SQLConstructor::QAttr.new( :name => 'ins_ignore', :text => 'IGNORE' ),
124
+ :on_duplicate_key_update => SQLConstructor::QAttr.new(
125
+ :name => 'ins_on_duplicate_key_update',
126
+ :text => 'ON DUPLICATE KEY UPDATE',
127
+ :val => SQLConditional
128
+ )
129
+ }
130
+
131
+ ##########################################################################
132
+ # Class constructor.
133
+ # _caller - the caller object
134
+ ##########################################################################
135
+ def initialize ( _caller )
136
+ super
137
+ end
138
+
139
+ end
140
+
141
+
142
+ ##########################################################################################
143
+ # MySQL dialect descendant of BasicUpdate class
144
+ ##########################################################################################
145
+ class SQLConstructor::BasicUpdate_mysql < SQLConstructor::BasicUpdate
146
+
147
+ attr_reader :upd_low_priority, :upd_ignore, :attr_limit
148
+
149
+ METHODS = {
150
+ :low_priority => SQLConstructor::QAttr.new( :name => 'upd_low_priority', :text => 'LOW_PRIORITY'),
151
+ :ignore => SQLConstructor::QAttr.new( :name => 'upd_ignore', :text => 'IGNORE' ),
152
+ :limit => SQLConstructor::QAttr.new( :name => 'attr_limit', :text => 'LIMIT',
153
+ :val => SQLObject )
154
+ }
155
+
156
+ ##########################################################################
157
+ # Class constructor.
158
+ # _caller - the caller object
159
+ ##########################################################################
160
+ def initialize ( _caller, *list )
161
+ super
162
+ end
163
+
164
+ end
165
+
166
+
167
+ ##########################################################################################
168
+ # MySQL dialect descendant of BasicJoin class
169
+ ##########################################################################################
170
+ class SQLConstructor::BasicJoin_mysql < SQLConstructor::BasicJoin
171
+
172
+ VALID_JOINS = [ "join", "inner_join", "cross_join", "left_join", "right_join",
173
+ "left_outer_join", "right_outer_join",
174
+ "natural_join", "natural_left_join", "natural_right_join",
175
+ "natural_left_outer_join", "natural_right_outer_join" ]
176
+
177
+ ##########################################################################
178
+ # Class contructor. Takes a caller object as the first argument, JOIN
179
+ # type as the second argument, and a list of sources for the JOIN clause
180
+ ##########################################################################
181
+ def initialize ( _caller, type, *sources )
182
+ type = type.to_s
183
+ if ! VALID_JOINS.include? type
184
+ raise NoMethodError, ERR_UNKNOWN_METHOD + ": " + type
185
+ end
186
+ super
187
+ end
188
+
189
+ ##########################################################################
190
+ # Adds a USE/FORCE/IGNORE INDEX clause for the last objects in for_vals
191
+ # argument.
192
+ ##########################################################################
193
+ def _addIndexes ( type, *list )
194
+ type = type.to_s
195
+ type.upcase!.gsub! /_/, ' '
196
+ @attr_index_hints ||= [ ]
197
+ # set the attr_index_hints for the last object in for_vals
198
+ last_ind = @join_sources.length - 1
199
+ @attr_index_hints[last_ind] = { :type => type, :list => SQLObject.get( list ) }
200
+ @string = nil
201
+ return self
202
+ end
203
+
204
+ ##########################################################################
205
+ # Export to string with index hints included
206
+ ##########################################################################
207
+ def to_s
208
+ return @string if @string
209
+ result = @type + " " + to_sWithAliasesIndexes( @join_sources )
210
+ result += @exporter.separator
211
+ result += "ON " + @join_on.val.to_s if @join_on
212
+ @string = result
213
+ end
214
+
215
+ ##########################################################################
216
+ # Handles INDEX hints or sends the call to the parent
217
+ ##########################################################################
218
+ def method_missing ( method, *args )
219
+ # Handle all valid *_index/*_key calls:
220
+ return _addIndexes( method, *args ) if VALID_INDEX_HINTS.include? method
221
+ super
222
+ end
223
+
224
+ ########
225
+ private
226
+ ########
227
+
228
+ ##########################################################################
229
+ # Returns a string of objects in list merged with @attr_index_hints
230
+ ##########################################################################
231
+ def to_sWithAliasesIndexes ( list )
232
+ list = [ list ] if ! [ Array, SQLValList, SQLAliasedList ].include? list.class
233
+ arr = [ ]
234
+ list.each_with_index do |item,i|
235
+ _alias = item.alias ? " " + item.alias.to_s : ""
236
+ str = item.to_s + _alias
237
+ if @attr_index_hints
238
+ index_hash = @attr_index_hints[i]
239
+ str += " " + index_hash[:type] + " " + index_hash[:list].to_s
240
+ end
241
+ arr << str
242
+ end
243
+ return arr.join ','
244
+ end
245
+
246
+ end
247
+
@@ -0,0 +1,108 @@
1
+
2
+ #####################################################################################
3
+ # MySQL dialect translator class.
4
+ #####################################################################################
5
+ class SQLExporter::Exporter_mysql < SQLExporter::Exporter_generic
6
+
7
+ attr_reader :dialect
8
+
9
+ # The main rule for the MySQL SELECT query syntax
10
+ SELECT_SYNTAX = [
11
+ "SELECT",
12
+ :attr_distinction,
13
+ :attr_high_priority,
14
+ :attr_straight_join,
15
+ :attr_sql_result_size,
16
+ :attr_sql_cache,
17
+ :attr_sql_calc_found_rows,
18
+ :attr_expression,
19
+ :attr_from,
20
+ :attr_joins,
21
+ :attr_where,
22
+ :attr_group_by,
23
+ :attr_group_by_order,
24
+ :attr_group_by_with_rollup,
25
+ :attr_having,
26
+ :attr_order_by,
27
+ :attr_order_by_order,
28
+ :attr_limit,
29
+ :attr_unions
30
+ ]
31
+
32
+ # The main rule for the MySQL DELETE query syntax
33
+ DELETE_SYNTAX = [
34
+ "DELETE",
35
+ :del_low_priority,
36
+ :del_quick,
37
+ :del_ignore,
38
+ :attr_from,
39
+ :attr_where,
40
+ :attr_order_by,
41
+ :attr_limit
42
+ ]
43
+
44
+ INSERT_SYNTAX = [
45
+ "INSERT",
46
+ :ins_priority,
47
+ :ins_ignore,
48
+ :ins_into,
49
+ :ins_values,
50
+ :ins_set,
51
+ :ins_select,
52
+ :ins_on_duplicate_key_update
53
+ ]
54
+
55
+ UPDATE_SYNTAX = [
56
+ "UPDATE",
57
+ :upd_low_priority,
58
+ :upd_ignore,
59
+ :upd_tables,
60
+ :upd_set,
61
+ :attr_where,
62
+ :attr_order_by,
63
+ :attr_limit
64
+ ]
65
+
66
+
67
+ def initialize ( tidy )
68
+ @tidy = tidy
69
+ @dialect = 'mysql'
70
+ super tidy # ha ha, "super tidy" :)
71
+ end
72
+
73
+ #############################################################################
74
+ # Forms a string for the FROM clause from the objects attributes @attr_from
75
+ # and @attr_index_hints
76
+ #############################################################################
77
+ def attr_from ( obj )
78
+ result = ""
79
+ if obj.attr_from
80
+ result = "FROM " + to_sWithAliasesIndexes( obj, obj.attr_from.val )
81
+ end
82
+ return result
83
+ end
84
+
85
+ ########
86
+ private
87
+ ########
88
+
89
+ #############################################################################
90
+ # Returns a string of objects in list merged with indexes of obj
91
+ #############################################################################
92
+ def to_sWithAliasesIndexes ( obj, list )
93
+ list = [ list ] if ! [ Array, SQLValList, SQLAliasedList ].include? list.class
94
+ arr = [ ]
95
+ list.each_with_index do |item,i|
96
+ _alias = item.alias ? " " + item.alias.to_s : ""
97
+ str = item.to_s + _alias
98
+ if obj.attr_index_hints
99
+ index_hash = obj.attr_index_hints[i]
100
+ str += " " + index_hash[:type] + " " + index_hash[:list].to_s
101
+ end
102
+ arr << str
103
+ end
104
+ return arr.join ','
105
+ end
106
+
107
+ end
108
+