baza 0.0.20 → 0.0.21

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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +84 -0
  3. data/.rubocop_todo.yml +17 -135
  4. data/.travis.yml +21 -0
  5. data/Gemfile +10 -7
  6. data/Gemfile.lock +39 -44
  7. data/README.md +61 -3
  8. data/VERSION +1 -1
  9. data/baza.gemspec +146 -98
  10. data/config/best_project_practice_rubocop.yml +8 -0
  11. data/config/best_project_practice_rubocop_todo.yml +6 -0
  12. data/lib/baza.rb +8 -12
  13. data/lib/baza/base_sql_driver.rb +198 -52
  14. data/lib/baza/cloner.rb +1 -0
  15. data/lib/baza/column.rb +26 -0
  16. data/lib/baza/database.rb +19 -3
  17. data/lib/baza/db.rb +69 -271
  18. data/lib/baza/driver.rb +1 -6
  19. data/lib/baza/{drivers → driver}/active_record.rb +65 -21
  20. data/lib/baza/{drivers → driver}/active_record/columns.rb +0 -0
  21. data/lib/baza/driver/active_record/commands.rb +10 -0
  22. data/lib/baza/driver/active_record/databases.rb +10 -0
  23. data/lib/baza/{drivers → driver}/active_record/indexes.rb +0 -0
  24. data/lib/baza/{drivers → driver}/active_record/result.rb +3 -1
  25. data/lib/baza/{drivers → driver}/active_record/tables.rb +0 -0
  26. data/lib/baza/driver/active_record/users.rb +12 -0
  27. data/lib/baza/{drivers → driver}/mysql.rb +9 -26
  28. data/lib/baza/{drivers → driver}/mysql/column.rb +14 -35
  29. data/lib/baza/{drivers → driver}/mysql/columns.rb +9 -12
  30. data/lib/baza/driver/mysql/commands.rb +39 -0
  31. data/lib/baza/driver/mysql/database.rb +64 -0
  32. data/lib/baza/driver/mysql/databases.rb +63 -0
  33. data/lib/baza/{drivers → driver}/mysql/index.rb +0 -0
  34. data/lib/baza/{drivers → driver}/mysql/indexes.rb +0 -0
  35. data/lib/baza/{drivers → driver}/mysql/result.rb +15 -7
  36. data/lib/baza/{drivers → driver}/mysql/sqlspecs.rb +0 -0
  37. data/lib/baza/{drivers → driver}/mysql/table.rb +27 -43
  38. data/lib/baza/{drivers → driver}/mysql/tables.rb +5 -34
  39. data/lib/baza/{drivers → driver}/mysql/unbuffered_result.rb +8 -2
  40. data/lib/baza/driver/mysql/user.rb +22 -0
  41. data/lib/baza/driver/mysql/users.rb +39 -0
  42. data/lib/baza/{drivers → driver}/mysql2.rb +19 -49
  43. data/lib/baza/{drivers → driver}/mysql2/column.rb +0 -0
  44. data/lib/baza/{drivers → driver}/mysql2/columns.rb +0 -0
  45. data/lib/baza/driver/mysql2/commands.rb +2 -0
  46. data/lib/baza/{drivers → driver}/mysql2/database.rb +0 -0
  47. data/lib/baza/{drivers → driver}/mysql2/databases.rb +0 -0
  48. data/lib/baza/{drivers → driver}/mysql2/index.rb +0 -0
  49. data/lib/baza/{drivers → driver}/mysql2/indexes.rb +0 -0
  50. data/lib/baza/{drivers → driver}/mysql2/result.rb +3 -1
  51. data/lib/baza/{drivers → driver}/mysql2/table.rb +0 -0
  52. data/lib/baza/{drivers → driver}/mysql2/tables.rb +0 -0
  53. data/lib/baza/driver/mysql2/user.rb +2 -0
  54. data/lib/baza/driver/mysql2/users.rb +2 -0
  55. data/lib/baza/{drivers → driver}/mysql_java.rb +60 -38
  56. data/lib/baza/{drivers → driver}/mysql_java/column.rb +0 -0
  57. data/lib/baza/{drivers → driver}/mysql_java/columns.rb +0 -0
  58. data/lib/baza/driver/mysql_java/commands.rb +2 -0
  59. data/lib/baza/driver/mysql_java/database.rb +2 -0
  60. data/lib/baza/driver/mysql_java/databases.rb +2 -0
  61. data/lib/baza/{drivers → driver}/mysql_java/index.rb +0 -0
  62. data/lib/baza/{drivers → driver}/mysql_java/indexes.rb +0 -0
  63. data/lib/baza/{drivers → driver}/mysql_java/table.rb +0 -0
  64. data/lib/baza/{drivers → driver}/mysql_java/tables.rb +0 -0
  65. data/lib/baza/driver/mysql_java/user.rb +2 -0
  66. data/lib/baza/driver/mysql_java/users.rb +2 -0
  67. data/lib/baza/driver/pg.rb +80 -0
  68. data/lib/baza/driver/pg/column.rb +125 -0
  69. data/lib/baza/driver/pg/columns.rb +37 -0
  70. data/lib/baza/driver/pg/commands.rb +35 -0
  71. data/lib/baza/driver/pg/create_index_sql_creator.rb +51 -0
  72. data/lib/baza/driver/pg/database.rb +89 -0
  73. data/lib/baza/driver/pg/databases.rb +79 -0
  74. data/lib/baza/driver/pg/index.rb +35 -0
  75. data/lib/baza/driver/pg/indexes.rb +5 -0
  76. data/lib/baza/driver/pg/result.rb +139 -0
  77. data/lib/baza/driver/pg/table.rb +184 -0
  78. data/lib/baza/driver/pg/tables.rb +45 -0
  79. data/lib/baza/{drivers → driver}/sqlite3.rb +6 -24
  80. data/lib/baza/{drivers → driver}/sqlite3/column.rb +22 -24
  81. data/lib/baza/{drivers → driver}/sqlite3/columns.rb +6 -6
  82. data/lib/baza/driver/sqlite3/commands.rb +28 -0
  83. data/lib/baza/{drivers → driver}/sqlite3/database.rb +0 -0
  84. data/lib/baza/{drivers → driver}/sqlite3/databases.rb +0 -1
  85. data/lib/baza/{drivers → driver}/sqlite3/index.rb +0 -0
  86. data/lib/baza/{drivers → driver}/sqlite3/indexes.rb +0 -0
  87. data/lib/baza/{drivers → driver}/sqlite3/result.rb +14 -6
  88. data/lib/baza/{drivers → driver}/sqlite3/sqlspecs.rb +0 -0
  89. data/lib/baza/{drivers → driver}/sqlite3/table.rb +25 -16
  90. data/lib/baza/{drivers → driver}/sqlite3/tables.rb +5 -6
  91. data/lib/baza/{drivers → driver}/sqlite3/unbuffered_result.rb +8 -2
  92. data/lib/baza/{drivers → driver}/sqlite3_java.rb +13 -23
  93. data/lib/baza/{drivers → driver}/sqlite3_java/column.rb +0 -0
  94. data/lib/baza/{drivers → driver}/sqlite3_java/columns.rb +0 -0
  95. data/lib/baza/driver/sqlite3_java/commands.rb +2 -0
  96. data/lib/baza/{drivers → driver}/sqlite3_java/database.rb +0 -0
  97. data/lib/baza/{drivers → driver}/sqlite3_java/index.rb +0 -0
  98. data/lib/baza/{drivers → driver}/sqlite3_java/indexes.rb +0 -0
  99. data/lib/baza/{drivers → driver}/sqlite3_java/table.rb +0 -0
  100. data/lib/baza/{drivers → driver}/sqlite3_java/tables.rb +0 -0
  101. data/lib/baza/{drivers → driver}/sqlite3_java/unbuffered_result.rb +14 -9
  102. data/lib/baza/{drivers → driver}/sqlite3_rhodes.rb +6 -24
  103. data/lib/baza/errors.rb +2 -0
  104. data/lib/baza/idquery.rb +15 -8
  105. data/lib/baza/index.rb +7 -0
  106. data/lib/baza/jdbc_driver.rb +4 -16
  107. data/lib/baza/jdbc_result.rb +20 -12
  108. data/lib/baza/mysql_base_driver.rb +7 -7
  109. data/lib/baza/query_buffer.rb +20 -19
  110. data/lib/baza/row.rb +16 -16
  111. data/lib/baza/sql_queries.rb +3 -0
  112. data/lib/baza/sql_queries/generic_insert.rb +81 -0
  113. data/lib/baza/sql_queries/generic_update.rb +31 -0
  114. data/lib/baza/sql_queries/mysql_upsert.rb +52 -0
  115. data/lib/baza/sql_queries/mysql_upsert_duplicate_key.rb +57 -0
  116. data/lib/baza/sql_queries/non_atomic_upsert.rb +25 -0
  117. data/lib/baza/sql_queries/postgres_upsert_duplicate_key.rb +118 -0
  118. data/lib/baza/sql_queries/select.rb +170 -0
  119. data/lib/baza/sql_queries/sqlite_upsert_duplicate_key.rb +99 -0
  120. data/lib/baza/table.rb +35 -8
  121. data/spec/active_record/models/user.rb +3 -0
  122. data/spec/{cloner_spec.rb → baza/cloner_spec.rb} +0 -0
  123. data/spec/drivers/active_record_mysql2_spec.rb +5 -3
  124. data/spec/drivers/active_record_mysql_spec.rb +2 -1
  125. data/spec/drivers/active_record_pg_spec.rb +20 -0
  126. data/spec/drivers/active_record_sqlite3_spec.rb +2 -1
  127. data/spec/drivers/mysql2_spec.rb +1 -1
  128. data/spec/drivers/mysql_spec.rb +10 -10
  129. data/spec/drivers/pg_spec.rb +18 -0
  130. data/spec/drivers/sqlite3_spec.rb +7 -8
  131. data/spec/info_active_record_example.rb +1 -1
  132. data/spec/{info_active_record_mysql2.rb → info_active_record_mysql2_example.rb} +3 -2
  133. data/spec/info_active_record_mysql2_travis.rb +35 -0
  134. data/spec/{info_active_record_mysql.rb → info_active_record_mysql_example.rb} +5 -4
  135. data/spec/info_active_record_mysql_travis.rb +36 -0
  136. data/spec/info_active_record_pg_example.rb +36 -0
  137. data/spec/info_active_record_pg_travis.rb +34 -0
  138. data/spec/info_active_record_sqlite3.rb +1 -1
  139. data/spec/info_mysql2_example.rb +1 -3
  140. data/spec/{info_mysql2_shippable.rb → info_mysql2_travis.rb} +2 -4
  141. data/spec/info_mysql_example.rb +1 -3
  142. data/spec/{info_mysql_shippable.rb → info_mysql_travis.rb} +2 -4
  143. data/spec/info_pg_example.rb +22 -0
  144. data/spec/info_pg_travis.rb +20 -0
  145. data/spec/info_sqlite3.rb +1 -3
  146. data/spec/spec_helper.rb +1 -1
  147. data/spec/support/driver_active_record_collection.rb +62 -0
  148. data/spec/support/driver_collection.rb +136 -121
  149. data/spec/support/driver_columns_collection.rb +19 -10
  150. data/spec/support/driver_databases_collection.rb +23 -1
  151. data/spec/support/driver_indexes_collection.rb +2 -2
  152. data/spec/support/driver_tables_collection.rb +24 -4
  153. data/spec/support/driver_users_collection.rb +53 -0
  154. metadata +185 -104
  155. data/lib/baza/drivers/mysql/database.rb +0 -28
  156. data/lib/baza/drivers/mysql/databases.rb +0 -35
  157. data/lib/baza/drivers/mysql_java/database.rb +0 -2
  158. data/lib/baza/drivers/mysql_java/databases.rb +0 -2
  159. data/lib/baza/model.rb +0 -875
  160. data/lib/baza/model_custom.rb +0 -155
  161. data/lib/baza/model_handler.rb +0 -910
  162. data/lib/baza/model_handler_sqlhelper.rb +0 -484
  163. data/lib/baza/revision.rb +0 -383
  164. data/shippable.yml +0 -17
  165. data/spec/info_active_record_mysql2_shippable.rb +0 -34
  166. data/spec/info_active_record_mysql_shippable.rb +0 -34
  167. data/spec/model_handler_spec.rb +0 -431
@@ -1,484 +0,0 @@
1
- require "ostruct"
2
-
3
- class Baza::ModelHandler
4
- # This method helps build SQL from Objects-instances list-method. It should not be called directly but only through Objects.list.
5
- def sqlhelper(list_args, args_def)
6
- args = args_def
7
-
8
- if args[:db]
9
- db = args[:db]
10
- else
11
- db = @args[:db]
12
- end
13
-
14
- if args[:table]
15
- table_def = "`#{db.escape_table(args[:table])}`."
16
- else
17
- table_def = ""
18
- end
19
-
20
- sql_joins = ""
21
- sql_where = ""
22
- sql_order = ""
23
- sql_limit = ""
24
- sql_groupby = ""
25
-
26
- do_joins = {}
27
-
28
- limit_from = nil
29
- limit_to = nil
30
-
31
- if list_args.key?("orderby")
32
- orders = []
33
- orderstr = list_args["orderby"]
34
- list_args["orderby"] = [list_args["orderby"]] if list_args["orderby"].is_a?(Hash)
35
-
36
- if list_args["orderby"].is_a?(String)
37
- found = false
38
- found = true if args[:cols].key?(orderstr)
39
-
40
- if found
41
- sql_order << " ORDER BY "
42
- ordermode = " ASC"
43
- if list_args.key?("ordermode")
44
- if list_args["ordermode"] == "desc"
45
- ordermode = " DESC"
46
- elsif list_args["ordermode"] == "asc"
47
- ordermode = " ASC"
48
- raise "Unknown ordermode: #{list_args["ordermode"]}"
49
- end
50
-
51
- list_args.delete("ordermode")
52
- end
53
-
54
- sql_order << "#{table_def}`#{db.escape_column(list_args["orderby"])}`#{ordermode}"
55
- list_args.delete("orderby")
56
- end
57
- elsif list_args["orderby"].is_a?(Array)
58
- sql_order << " ORDER BY "
59
-
60
- list_args["orderby"].each do |val|
61
- ordermode = nil
62
- orderstr = nil
63
- found = false
64
-
65
- if val.is_a?(Array)
66
- if val[1] == "asc"
67
- ordermode = " ASC"
68
- elsif val[1] == "desc"
69
- ordermode = " DESC"
70
- end
71
-
72
- if val[0].is_a?(Array)
73
- if args[:joined_tables]
74
- args[:joined_tables].each do |table_name, _table_data|
75
- next if table_name.to_s != val[0][0].to_s
76
- do_joins[table_name] = true
77
- orders << "`#{db.escape_table(table_name)}`.`#{db.escape_column(val[0][1])}`#{ordermode}"
78
- found = true
79
- break
80
- end
81
- end
82
-
83
- raise "Could not find joined table for ordering: '#{val[0][0]}'." unless found
84
- else
85
- orderstr = val[0]
86
- end
87
- elsif val.is_a?(String)
88
- orderstr = val
89
- ordermode = " ASC"
90
- elsif val.is_a?(Hash) && val[:type] == :sql
91
- orders << val[:sql]
92
- found = true
93
- elsif val.is_a?(Hash) && val[:type] == :case
94
- caseorder = " CASE"
95
-
96
- val[:case].each do |key, caseval|
97
- col = key.first
98
- isval = key.last
99
- col_str = nil
100
-
101
- if col.is_a?(Array)
102
- raise "No joined tables for '#{args[:table]}'." unless args[:joined_tables]
103
-
104
- found = false
105
- args[:joined_tables].each do |table_name, _table_data|
106
- next unless table_name == col.first
107
- do_joins[table_name] = true
108
- col_str = "`#{db.escape_table(table_name)}`.`#{db.escape_column(col.last)}`"
109
- found = true
110
- break
111
- end
112
-
113
- raise "No such joined table on '#{args[:table]}': '#{col.first}' (#{col.first.class.name}) with the following joined table:\n#{Php4r.print_r(args[:joined_tables], true)}" unless found
114
- elsif col.is_a?(String) || col.is_a?(Symbol)
115
- col_str = "#{table_def}`#{col}`"
116
- found = true
117
- else
118
- raise "Unknown type for case-ordering: '#{col.class.name}'."
119
- end
120
-
121
- raise "'colstr' was not set." unless col_str
122
- caseorder << " WHEN #{col_str} = '#{db.esc(isval)}' THEN '#{db.esc(caseval)}'"
123
- end
124
-
125
- caseorder << " ELSE '#{db.esc(val[:else])}'" if val[:else]
126
-
127
- caseorder << " END"
128
- orders << caseorder
129
- elsif val.is_a?(Hash)
130
- raise "No joined tables." unless args.key?(:joined_tables)
131
-
132
- if val[:mode] == "asc"
133
- ordermode = " ASC"
134
- elsif val[:mode] == "desc"
135
- ordermode = " DESC"
136
- end
137
-
138
- if args[:joined_tables]
139
- args[:joined_tables].each do |table_name, table_data|
140
- if table_data[:parent_table]
141
- table_name_real = table_name
142
- elsif table_data[:datarow]
143
- table_name_real = datarow_from_datarow_argument(table_data[:datarow]).classname
144
- else
145
- table_name_real = @args[:module].const_get(table_name).classname
146
- end
147
-
148
- next unless table_name.to_s == val[:table].to_s
149
- do_joins[table_name] = true
150
-
151
- if val[:sql]
152
- orders << val[:sql]
153
- elsif val[:col]
154
- orders << "`#{db.escape_table(table_name_real)}`.`#{db.escape_column(val[:col])}`#{ordermode}"
155
- else
156
- raise "Couldnt figure out how to order based on keys: '#{val.keys.sort}'."
157
- end
158
-
159
- found = true
160
- break
161
- end
162
- end
163
- else
164
- raise "Unknown object: #{val.class.name}"
165
- end
166
-
167
- found = true if args[:cols].key?(orderstr)
168
-
169
- raise "Column not found for ordering: #{orderstr}." unless found
170
-
171
- orders << "#{table_def}`#{db.escape_column(orderstr)}`#{ordermode}" if orderstr
172
- end
173
-
174
- sql_order << orders.join(", ")
175
- list_args.delete("orderby")
176
- else
177
- raise "Unknown orderby object: #{list_args["orderby"].class.name}."
178
- end
179
- end
180
-
181
- list_args.each do |realkey, val|
182
- found = false
183
-
184
- if realkey.is_a?(Array)
185
- if !args[:joins_skip]
186
- datarow_obj = datarow_obj_from_args(args_def, list_args, realkey[0])
187
- args = datarow_obj.columns_sqlhelper_args
188
- raise "Couldnt get arguments from SQLHelper." unless args
189
- else
190
- datarow_obj = @args[:module].const_get(realkey[0])
191
- args = args_def
192
- end
193
-
194
- table_sym = realkey[0].to_sym
195
- do_joins[table_sym] = true
196
- list_table_name_real = table_sym
197
- table = "`#{db.escape_table(list_table_name_real)}`."
198
- key = realkey[1]
199
- else
200
- table = table_def
201
- args = args_def
202
- key = realkey
203
- end
204
-
205
- if args.key?(:cols_bools) && !args[:cols_bools].index(key).nil?
206
- val_s = val.to_s
207
-
208
- if val_s == "1" || val_s == "true"
209
- realval = "1"
210
- elsif val_s == "0" || val_s == "false"
211
- realval = "0"
212
- else
213
- raise "Could not make real value out of class: #{val.class.name} => #{val}."
214
- end
215
-
216
- sql_where << " AND #{table}`#{db.escape_column(key)}` = '#{db.esc(realval)}'"
217
- found = true
218
- elsif args[:cols].key?(key.to_s)
219
- if val.is_a?(Array)
220
- if val.empty? && db.opts[:type].to_s == "mysql"
221
- sql_where << " AND false"
222
- else
223
- escape_sql = val.map { |v| "'#{db.escape(v)}'" }.join(",")
224
- sql_where << " AND #{table}`#{db.escape_column(key)}` IN (#{escape_sql})"
225
- end
226
- elsif val.is_a?(Hash) && val[:type].to_sym == :col
227
- raise "No table was given for join: '#{val}', key: '#{key}' on table #{table}." unless val.key?(:table)
228
- do_joins[val[:table].to_sym] = true
229
- sql_where << " AND #{table}`#{db.escape_column(key)}` = `#{db.escape_table(val[:table])}`.`#{db.escape_column(val[:name])}`"
230
- elsif val.is_a?(Hash) && val[:type] == :sqlval && val[:val] == :null
231
- sql_where << " AND #{table}`#{db.escape_column(key)}` IS NULL"
232
- elsif val.is_a?(Proc)
233
- call_args = OpenStruct.new(ob: self, db: db)
234
- sql_where << " AND #{table}`#{db.escape_column(key)}` = '#{db.esc(val.call(call_args))}'"
235
- else
236
- sql_where << " AND #{table}`#{db.escape_column(key)}` = '#{db.esc(val)}'"
237
- end
238
-
239
- found = true
240
- elsif key.to_s == "limit_from"
241
- limit_from = val.to_i
242
- found = true
243
- elsif key.to_s == "limit_to"
244
- limit_to = val.to_i
245
- found = true
246
- elsif key.to_s == "limit"
247
- limit_from = 0
248
- limit_to = val.to_i
249
- found = true
250
- elsif args.key?(:cols_dbrows) && !args[:cols_dbrows].index("#{key}_id").nil?
251
- if val == false
252
- sql_where << " AND #{table}`#{db.escape_column(key.to_s + "_id")}` = '0'"
253
- elsif val.is_a?(Array)
254
- if val.empty?
255
- sql_where << " AND false"
256
- else
257
- sql_where << " AND #{table}`#{db.escape_column("#{key}_id")}` IN (#{Knj::ArrayExt.join(arr: val, sep: ",", surr: "'", callback: proc { |obj| obj.id.sql })})"
258
- end
259
- else
260
- sql_where << " AND #{table}`#{db.escape_column(key.to_s + "_id")}` = '#{db.esc(val.id)}'"
261
- end
262
-
263
- found = true
264
- elsif match = key.match(/^([A-z_\d]+)_(search|has)$/) && !args[:cols].key?(match[1]).nil?
265
- if match[2] == "search"
266
- Knj::Strings.searchstring(val).each do |str|
267
- sql_where << " AND #{table}`#{db.escape_column(match[1])}` LIKE '%#{db.esc(str)}%'"
268
- end
269
- elsif match[2] == "has"
270
- if val
271
- sql_where << " AND #{table}`#{db.escape_column(match[1])}` != ''"
272
- else
273
- sql_where << " AND #{table}`#{db.escape_column(match[1])}` = ''"
274
- end
275
- end
276
-
277
- found = true
278
- elsif match = key.match(/^([A-z_\d]+)_(not|lower)$/) && args[:cols].key?(match[1])
279
- if match[2] == "not"
280
- if val.is_a?(Array)
281
- if val.empty?
282
- # ignore.
283
- else
284
- escape_sql = Knj::ArrayExt.join(
285
- arr: val,
286
- callback: proc do|value|
287
- db.escape(value)
288
- end,
289
- sep: ",",
290
- surr: "'"
291
- )
292
- sql_where << " AND #{table}`#{db.escape_column(match[1])}` NOT IN (#{escape_sql})"
293
- end
294
- else
295
- sql_where << " AND #{table}`#{db.escape_column(match[1])}` != '#{db.esc(val)}'"
296
- end
297
- elsif match[2] == "lower"
298
- sql_where << " AND LOWER(#{table}`#{db.escape_column(match[1])}`) = LOWER('#{db.esc(val)}')"
299
- else
300
- raise "Unknown mode: '#{match[2]}'."
301
- end
302
-
303
- found = true
304
- elsif args.key?(:cols_date) && (match = key.match(/^(.+)_(day|week|month|year|from|to|below|above)(|_(not))$/)) && !args[:cols_date].index(match[1]).nil?
305
- not_v = match[4]
306
- val = Datet.in(val) if val.is_a?(Time)
307
-
308
- if match[2] == "day"
309
- if val.is_a?(Array)
310
- sql_where << " AND ("
311
- first = true
312
-
313
- val.each do |dayval|
314
- if first
315
- first = false
316
- else
317
- sql_where << " OR "
318
- end
319
-
320
- sql_where << "#{db.sqlspecs.strftime("%d %m %Y", "#{table}`#{db.escape_column(match[1])}`")} #{self.not(not_v, "!")}= #{db.sqlspecs.strftime("%d %m %Y", "'#{db.esc(dayval.dbstr)}'")}"
321
- end
322
-
323
- sql_where << ")"
324
- else
325
- sql_where << " AND #{db.sqlspecs.strftime("%d %m %Y", "#{table}`#{db.escape_column(match[1])}`")} #{self.not(not_v, "!")}= #{db.sqlspecs.strftime("%d %m %Y", "'#{db.esc(val.dbstr)}'")}"
326
- end
327
- elsif match[2] == "week"
328
- sql_where << " AND #{db.sqlspecs.strftime("%W %Y", "#{table}`#{db.escape_column(match[1])}`")} #{self.not(not_v, "!")}= #{db.sqlspecs.strftime("%W %Y", "'#{db.esc(val.dbstr)}'")}"
329
- elsif match[2] == "month"
330
- sql_where << " AND #{db.sqlspecs.strftime("%m %Y", "#{table}`#{db.escape_column(match[1])}`")} #{self.not(not_v, "!")}= #{db.sqlspecs.strftime("%m %Y", "'#{db.esc(val.dbstr)}'")}"
331
- elsif match[2] == "year"
332
- sql_where << " AND #{db.sqlspecs.strftime("%Y", "#{table}`#{db.escape_column(match[1])}`")} #{self.not(not_v, "!")}= #{db.sqlspecs.strftime("%Y", "'#{db.esc(val.dbstr)}'")}"
333
- elsif match[2] == "from" || match[2] == "above"
334
- sql_where << " AND #{table}`#{db.escape_column(match[1])}` >= '#{db.esc(val.dbstr)}'"
335
- elsif match[2] == "to" || match[2] == "below"
336
- sql_where << " AND #{table}`#{db.escape_column(match[1])}` <= '#{db.esc(val.dbstr)}'"
337
- else
338
- raise "Unknown date-key: #{match[2]}."
339
- end
340
-
341
- found = true
342
- elsif args.key?(:cols_num) && match = key.match(/^(.+)_(from|to|above|below|numeric)$/) && !args[:cols_num].index(match[1]).nil?
343
- if match[2] == "from"
344
- sql_where << " AND #{table}`#{db.escape_column(match[1])}` >= '#{db.esc(val)}'"
345
- elsif match[2] == "to"
346
- sql_where << " AND #{table}`#{db.escape_column(match[1])}` <= '#{db.esc(val)}'"
347
- elsif match[2] == "above"
348
- sql_where << " AND #{table}`#{db.escape_column(match[1])}` > '#{db.esc(val)}'"
349
- elsif match[2] == "below"
350
- sql_where << " AND #{table}`#{db.escape_column(match[1])}` < '#{db.esc(val)}'"
351
- else
352
- raise "Unknown method of treating cols-num-argument: #{match[2]}."
353
- end
354
-
355
- found = true
356
- elsif match = key.match(/^(.+)_lookup$/) && args[:cols].key?("#{match[1]}_id") && args[:cols].key?("#{match[1]}_class")
357
- sql_where << " AND #{table}`#{db.escape_column("#{match[1]}_class")}` = '#{db.esc(val.table)}'"
358
- sql_where << " AND #{table}`#{db.escape_column("#{match[1]}_id")}` = '#{db.esc(val.id)}'"
359
- found = true
360
- elsif realkey == "groupby"
361
- found = true
362
-
363
- if val.is_a?(Array)
364
- val.each do |col_name|
365
- raise "Column '#{val}' not found on table '#{table}'." unless args[:cols].key?(col_name)
366
- sql_groupby << ", " if sql_groupby.length > 0
367
- sql_groupby << "#{table}`#{db.escape_column(col_name)}`"
368
- end
369
- elsif val.is_a?(String)
370
- sql_groupby << ", " if sql_groupby.length > 0
371
- sql_groupby << "#{table}`#{db.escape_column(val)}`"
372
- else
373
- raise "Unknown class given for 'groupby': '#{val.class.name}'."
374
- end
375
- end
376
-
377
- list_args.delete(realkey) if found
378
- end
379
-
380
- args = args_def
381
-
382
- unless args[:joins_skip]
383
- raise "No joins defined on '#{args[:table]}' for: '#{args[:table]}'." if !do_joins.empty? && !args[:joined_tables]
384
-
385
- do_joins.each do |table_name, _temp_val|
386
- raise "No join defined on table '#{args[:table]}' for table '#{table_name}'." unless args[:joined_tables].key?(table_name)
387
- table_data = args[:joined_tables][table_name]
388
-
389
- if table_data.key?(:parent_table)
390
- join_table_name_real = table_name
391
- sql_joins << " LEFT JOIN `#{table_data[:parent_table]}` AS `#{table_name}` ON 1=1"
392
- else
393
- const = @args[:module].const_get(table_name)
394
- join_table_name_real = const.classname
395
- sql_joins << " LEFT JOIN `#{const.table}` AS `#{const.classname}` ON 1=1"
396
- end
397
-
398
- if table_data[:ob]
399
- ob = table_data[:ob]
400
- else
401
- ob = self
402
- end
403
-
404
- class_name = args[:table].to_sym
405
-
406
- if table_data[:datarow]
407
- datarow = datarow_from_datarow_argument(table_data[:datarow])
408
- else
409
- requireclass(class_name) if @objects.key?(class_name)
410
- datarow = @args[:module].const_get(class_name)
411
- end
412
-
413
- unless datarow.columns_sqlhelper_args
414
- ob.requireclass(datarow.table.to_sym)
415
- raise "No SQL-helper-args on class '#{datarow.table}' ???" unless datarow.columns_sqlhelper_args
416
- end
417
-
418
- newargs = datarow.columns_sqlhelper_args.clone
419
- newargs[:table] = join_table_name_real
420
- newargs[:joins_skip] = true
421
-
422
- # Clone the where-arguments and run them against another sqlhelper to sub-join.
423
- join_args = table_data[:where].clone
424
- ret = sqlhelper(join_args, newargs)
425
- sql_joins << ret[:sql_where]
426
-
427
- # If any of the join-arguments are left, then we should throw an error.
428
- join_args.each_key do |key|
429
- raise "Invalid key '#{key}' when trying to join table '#{table_name}' on table '#{args_def[:table]}'."
430
- end
431
- end
432
- end
433
-
434
- # If limit arguments has been given then add them.
435
- sql_limit = " LIMIT #{limit_from}, #{limit_to}" if limit_from && limit_to
436
-
437
- sql_groupby = nil if sql_groupby.empty?
438
-
439
- {
440
- sql_joins: sql_joins,
441
- sql_where: sql_where,
442
- sql_limit: sql_limit,
443
- sql_order: sql_order,
444
- sql_groupby: sql_groupby
445
- }
446
- end
447
-
448
- # Used by sqlhelper-method to look up datarow-classes and automatically load them if they arent loaded already.
449
- def datarow_obj_from_args(args, _list_args, class_name)
450
- class_name = class_name.to_sym
451
-
452
- unless args.key?(:joined_tables)
453
- raise "No joined tables on '#{args[:table]}' to find datarow for: '#{class_name}'."
454
- end
455
-
456
- args[:joined_tables].each do |table_name, table_data|
457
- next if table_name.to_sym != class_name
458
- return datarow_from_datarow_argument(table_data[:datarow]) if table_data[:datarow]
459
-
460
- requireclass(class_name) if @objects.key?(class_name)
461
- return @args[:module].const_get(class_name)
462
- end
463
-
464
- raise "Could not figure out datarow for: '#{class_name}'."
465
- end
466
-
467
- def datarow_from_datarow_argument(datarow_argument)
468
- if datarow_argument.is_a?(String)
469
- const = Knj::Strings.const_get_full(datarow_argument)
470
- else
471
- const = datarow_argument
472
- end
473
-
474
- load_class(datarow_argument.to_s.split("::").last) unless const.initialized? # Make sure the class is initialized.
475
-
476
- const
477
- end
478
-
479
- def not(not_v, val)
480
- return val if not_v == "not" || not_v == "not_"
481
-
482
- ""
483
- end
484
- end