baza 0.0.20 → 0.0.21

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