webink 1.2.9 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/rfcgi CHANGED
File without changes
File without changes
@@ -153,7 +153,11 @@ module Ink
153
153
  re.each_hash do |row|
154
154
  result.push Hash.new
155
155
  row.each do |k,v|
156
- v = $&.to_i if v =~ /^[0-9]+$/
156
+ if v =~ /^[0-9]+$/
157
+ v = $&.to_i
158
+ elsif v =~ /^[0-9]+\.[0-9]+$/
159
+ v = $&.to_f
160
+ end
157
161
  result[result.length-1][k] = v
158
162
  end
159
163
  end
@@ -163,7 +167,11 @@ module Ink
163
167
  re.each do |row|
164
168
  result.push Hash.new
165
169
  for i in 0...re.columns.length
166
- row[i] = $&.to_i if row[i] =~ /^[0-9]+$/
170
+ if row[i] =~ /^[0-9]+$/
171
+ row[i] = $&.to_i
172
+ elsif row[i] =~ /^[0-9]+\.[0-9]+$/
173
+ row[i] = $&.to_f
174
+ end
167
175
  result[result.length-1][re.columns[i]] = row[i]
168
176
  end
169
177
  end
@@ -191,10 +199,12 @@ module Ink
191
199
  # Instance method
192
200
  #
193
201
  # Attempts to fetch the last inserted primary key
202
+ # [param class_name:] Defines the __table__ name or class
194
203
  # [returns:] primary key or nil
195
204
  def last_inserted_pk(class_name)
196
- table_name = Ink::Model.str_to_tablename(class_name)
197
- pk_name = Ink::Model.classname(class_name).primary_key[0]
205
+ c = (class_name.is_a? Class) ? class_name : Ink::Model.classname(class_name)
206
+ table_name = c.table_name
207
+ pk_name = c.primary_key[0]
198
208
  return if not (table_name and pk_name)
199
209
  response = self.query("SELECT MAX(#{pk_name}) as id FROM #{table_name};")
200
210
  return (response.length > 0) ? response[0]["id"] : nil
@@ -218,10 +228,10 @@ module Ink
218
228
  # Instance method
219
229
  #
220
230
  # Delete something from the database.
221
- # [param class_name:] Defines the table name
231
+ # [param class_name:] Defines the class name or class
222
232
  # [param params:] Additional SQL syntax like WHERE conditions (optional)
223
233
  def remove(class_name, params="")
224
- table_name = Ink::Model.str_to_tablename(class_name)
234
+ table_name = (class_name.is_a? Class) ? class_name.table_name : Ink::Model.str_to_tablename(class_name)
225
235
  return if not table_name
226
236
  self.query("DELETE FROM #{table_name} #{params};")
227
237
  end
@@ -229,17 +239,18 @@ module Ink
229
239
  # Instance method
230
240
  #
231
241
  # Retrieve class instances, that are loaded with the database result set.
232
- # [param class_name:] Defines the table name and resulting Instance classnames
242
+ # [param class_name:] Defines the class name or class which should be queried
233
243
  # [param params:] Additional SQL syntax like WHERE conditions (optional)
234
244
  # [returns:] Array of class_name instances from the SQL result set
235
245
  def find(class_name, params="")
246
+ c = (class_name.is_a? Class) ? class_name : Ink::Model.classname(class_name)
236
247
  result = Array.new
237
- table_name = Ink::Model.str_to_tablename(class_name)
248
+ table_name = c.table_name
238
249
  return result if not table_name
239
250
 
240
251
  re = self.query("SELECT * FROM #{table_name} #{params};")
241
252
  re.each do |entry|
242
- instance = Ink::Model.classname(class_name).new entry
253
+ instance = c.new entry
243
254
  result.push instance
244
255
  end
245
256
  result
@@ -250,27 +261,29 @@ module Ink
250
261
  # Retrieve class2 instances, that are related to the class1 instance with
251
262
  # primary key class1_id. This is done via an additional relationship table.
252
263
  # Only relevant for many_many relationships.
253
- # [param class1:] Reference classname
264
+ # [param class1:] Reference classname or class
254
265
  # [param class1_id:] Primary key value of the reference classname
255
- # [param class2:] Match classname
266
+ # [param class2:] Match classname or class
256
267
  # [param params:] Additional SQL syntax like GROUP BY (optional)
257
268
  # [returns:] Array of class2 instances from the SQL result set
258
269
  def find_union(class1, class1_id, class2, params="")
270
+ c1 = (class1.is_a? Class) ? class1 : Ink::Model.classname(class1)
271
+ c2 = (class2.is_a? Class) ? class2 : Ink::Model.classname(class2)
259
272
  result = Array.new
260
273
  relationship = nil
261
- Ink::Model.classname(class1).foreign.each do |k,v|
262
- relationship = v if k.downcase == class2.downcase
274
+ c1.foreign.each do |k,v|
275
+ relationship = v if k.downcase == c2.class_name.downcase
263
276
  end
264
277
  return result if relationship != "many_many"
265
- fk1 = Ink::Model.classname(class1).foreign_key[0]
266
- pk2 = Ink::Model.classname(class2).primary_key[0]
267
- fk2 = Ink::Model.classname(class2).foreign_key[0]
268
- tablename1 = Ink::Model.str_to_tablename(class1)
269
- tablename2 = Ink::Model.str_to_tablename(class2)
270
- union_class = ((class1.downcase <=> class2.downcase) < 0) ? "#{tablename1}_#{tablename2}" : "#{tablename2}_#{tablename1}"
278
+ fk1 = c1.foreign_key[0]
279
+ pk2 = c2.primary_key[0]
280
+ fk2 = c2.foreign_key[0]
281
+ tablename1 = c1.table_name
282
+ tablename2 = c2.table_name
283
+ union_class = ((c1.class_name.downcase <=> c2.class_name.downcase) < 0) ? "#{tablename1}_#{tablename2}" : "#{tablename2}_#{tablename1}"
271
284
  re = self.query("SELECT #{tablename2}.* FROM #{union_class}, #{tablename2} WHERE #{union_class}.#{fk1} = #{class1_id} AND #{union_class}.#{fk2} = #{tablename2}.#{pk2} #{params};")
272
285
  re.each do |entry|
273
- instance = Ink::Model.classname(tablename2).new entry
286
+ instance = c2.new entry
274
287
  result.push instance
275
288
  end
276
289
  result
@@ -280,33 +293,55 @@ module Ink
280
293
  #
281
294
  # Retrieve class2 instances, that are related to the class1 instance with
282
295
  # primary key class1_id. Not relevant for many_many relationships
283
- # [param class1:] Reference classname
296
+ # [param class1:] Reference classname or class
284
297
  # [param class1_id:] Primary key value of the reference classname
285
- # [param class2:] Match classname
298
+ # [param class2:] Match classname or class
286
299
  # [param params:] Additional SQL syntax like GROUP BY (optional)
287
300
  # [returns:] Array of class2 instances from the SQL result set
288
301
  def find_references(class1, class1_id, class2, params="")
302
+ c1 = (class1.is_a? Class) ? class1 : Ink::Model.classname(class1)
303
+ c2 = (class2.is_a? Class) ? class2 : Ink::Model.classname(class2)
289
304
  result = Array.new
290
305
  relationship = nil
291
- Ink::Model.classname(class1).foreign.each do |k,v|
292
- relationship = v if k.downcase == class2.downcase
306
+ c1.foreign.each do |k,v|
307
+ relationship = v if k.downcase == c2.class_name.downcase
293
308
  end
294
309
  return result if relationship == "many_many"
295
310
  re = Array.new
296
- fk1 = Ink::Model.classname(class1).foreign_key[0]
297
- if ((class1.downcase <=> class2.downcase) < 0 and relationship == "one_one") or relationship == "one_many"
298
- re = self.query "SELECT * FROM #{Ink::Model.str_to_tablename(class2)} WHERE #{Ink::Model.classname(class2).primary_key[0]}=(SELECT #{Ink::Model.classname(class2).foreign_key[0]} FROM #{Ink::Model.str_to_tablename(class1)} WHERE #{Ink::Model.classname(class1).primary_key[0]}=#{class1_id});"
311
+ fk1 = c1.foreign_key[0]
312
+ tablename1 = c1.table_name
313
+ tablename2 = c2.table_name
314
+ if ((c1.class_name.downcase <=> c2.class_name.downcase) < 0 and relationship == "one_one") or relationship == "one_many"
315
+ re = self.query "SELECT * FROM #{tablename2} WHERE #{c2.primary_key[0]}=(SELECT #{c2.foreign_key[0]} FROM #{tablename1} WHERE #{c1.primary_key[0]}=#{class1_id});"
299
316
  else
300
- re = self.query "SELECT * FROM #{Ink::Model.str_to_tablename(class2)} WHERE #{fk1} = #{class1_id} #{params};"
317
+ re = self.query "SELECT * FROM #{tablename2} WHERE #{fk1} = #{class1_id} #{params};"
301
318
  end
302
319
 
303
320
  re.each do |entry|
304
- instance = Ink::Model.classname(class2).new entry
321
+ instance = c2.new entry
305
322
  result.push instance
306
323
  end
307
324
  result
308
325
  end
309
326
 
327
+ # Instance method
328
+ #
329
+ # Retrieve one class2 instance, that is related to the class1 instance with
330
+ # primary key class1_id. Only relevant for one_one and one_many relationships
331
+ # [param class1:] Reference classname or class
332
+ # [param class1_id:] Primary key value of the reference classname
333
+ # [param class2:] Match classname or class
334
+ # [param params:] Additional SQL syntax like GROUP BY (optional)
335
+ # [returns:] single class2 instance from the SQL result set
336
+ def find_reference(class1, class1_id, class2, params="")
337
+ result_array = self.find_references class1, class1_id, class2, params
338
+ if result_array.length == 1
339
+ result_array[0]
340
+ else
341
+ nil
342
+ end
343
+ end
344
+
310
345
  # Instance method
311
346
  #
312
347
  # This method attempts to remove all existing relationship data
@@ -322,16 +357,16 @@ module Ink
322
357
  secondclass = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? link : instance.class
323
358
  key = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? instance.class.primary_key[0] : instance.class.foreign_key[0]
324
359
  value = instance.method(instance.class.primary_key[0]).call
325
- @db.query "UPDATE #{Ink::Model.str_to_tablename(firstclass.name)} SET #{secondclass.foreign_key[0]}=NULL WHERE #{key}=#{value};"
360
+ @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key[0]}=NULL WHERE #{key}=#{value};"
326
361
  elsif type == "one_many" or type == "many_one"
327
362
  firstclass = (type == "one_many") ? instance.class : link
328
363
  secondclass = (type == "one_many") ? link : instance.class
329
364
  key = (type == "one_many") ? instance.class.primary_key[0] : instance.class.foreign_key[0]
330
365
  value = instance.method(instance.class.primary_key[0]).call
331
- @db.query "UPDATE #{Ink::Model.str_to_tablename(firstclass.name)} SET #{secondclass.foreign_key[0]}=NULL WHERE #{key}=#{value};"
366
+ @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key[0]}=NULL WHERE #{key}=#{value};"
332
367
  elsif type == "many_many"
333
- tablename1 = Ink::Model.str_to_tablename(instance.class.name)
334
- tablename2 = Ink::Model.str_to_tablename(link.name)
368
+ tablename1 = instance.class.table_name
369
+ tablename2 = link.table_name
335
370
  union_class = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? "#{tablename1}_#{tablename2}" : "#{tablename2}_#{tablename1}"
336
371
  value = instance.method(instance.class.primary_key[0]).call
337
372
  @db.query "DELETE FROM #{union_class} WHERE #{instance.class.foreign_key[0]}=#{value};"
@@ -390,7 +425,7 @@ module Ink
390
425
  value = instance.method(instance.class.primary_key[0]).call
391
426
  fk_set = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? fk : value
392
427
  value_set = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? value : fk
393
- @db.query "UPDATE #{Ink::Model.str_to_tablename(firstclass.name)} SET #{secondclass.foreign_key[0]}=#{fk} WHERE #{key}=#{value};"
428
+ @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key[0]}=#{fk} WHERE #{key}=#{value};"
394
429
  elsif type == "one_many" or type == "many_one"
395
430
  firstclass = (type == "one_many") ? instance.class : link
396
431
  secondclass = (type == "one_many") ? link : instance.class
@@ -398,10 +433,10 @@ module Ink
398
433
  value = instance.method(instance.class.primary_key[0]).call
399
434
  fk_set = (type == "one_many") ? fk : value
400
435
  value_set = (type == "one_many") ? value : fk
401
- @db.query "UPDATE #{Ink::Model.str_to_tablename(firstclass.name)} SET #{secondclass.foreign_key[0]}=#{fk_set} WHERE #{key}=#{value_set};"
436
+ @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key[0]}=#{fk_set} WHERE #{key}=#{value_set};"
402
437
  elsif type == "many_many"
403
- tablename1 = Ink::Model.str_to_tablename(instance.class.name)
404
- tablename2 = Ink::Model.str_to_tablename(link.name)
438
+ tablename1 = instance.class.table_name
439
+ tablename2 = link.table_name
405
440
  union_class = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? "#{tablename1}_#{tablename2}" : "#{tablename2}_#{tablename1}"
406
441
  value = instance.method(instance.class.primary_key[0]).call
407
442
  @db.query "INSERT INTO #{union_class} (#{instance.class.foreign_key[0]}, #{link.foreign_key[0]}) VALUES (#{value}, #{fk});"
@@ -131,13 +131,14 @@ module Ink
131
131
  end
132
132
  if self.class.respond_to? :foreign
133
133
  self.class.foreign.each do |k,v|
134
- raise NameError.new("Model cannot use #{k} as foreign, it already exists") if self.class.respond_to? k.to_sym or k.downcase == "pk"
135
- instance_variable_set "@#{self.class.str_to_tablename(k)}", nil
136
- self.class.send(:define_method, k.downcase) do
137
- instance_variable_get "@#{k.downcase}"
134
+ k_table = self.class.str_to_tablename(k)
135
+ raise NameError.new("Model cannot use #{k_table} as foreign, it already exists") if self.class.respond_to? k_table.to_sym or k_table == "pk"
136
+ instance_variable_set("@#{k_table}", nil)
137
+ self.class.send(:define_method, k_table) do
138
+ instance_variable_get "@#{k_table}"
138
139
  end
139
- self.class.send(:define_method, "#{k.downcase}=") do |val|
140
- instance_variable_set "@#{k.downcase}", val
140
+ self.class.send(:define_method, "#{k_table}=") do |val|
141
+ instance_variable_set "@#{k_table}", val
141
142
  end
142
143
  end
143
144
  end
@@ -183,12 +184,12 @@ module Ink
183
184
  end
184
185
  end
185
186
  if pkvalue
186
- response = Ink::Database.database.find self.class.name, pkvalue
187
+ response = Ink::Database.database.find self.class, pkvalue
187
188
  if response.length == 1
188
- Ink::Database.database.query "UPDATE #{Ink::Model.str_to_tablename(self.class.name)} SET #{string * ","} #{pkvalue}"
189
+ Ink::Database.database.query "UPDATE #{self.class.table_name} SET #{string * ","} #{pkvalue}"
189
190
  elsif response.length == 0
190
- Ink::Database.database.query "INSERT INTO #{Ink::Model.str_to_tablename(self.class.name)} (#{keystring * ","}) VALUES (#{valuestring * ","});"
191
- pk = Ink::Database.database.last_inserted_pk(self.class.name)
191
+ Ink::Database.database.query "INSERT INTO #{self.class.table_name} (#{keystring * ","}) VALUES (#{valuestring * ","});"
192
+ pk = Ink::Database.database.last_inserted_pk(self.class)
192
193
  instance_variable_set "@#{self.class.primary_key[0]}", pk.is_a?(Numeric) ? pk : "\'#{pk}\'" if pk
193
194
  end
194
195
  end
@@ -221,6 +222,23 @@ module Ink
221
222
  Ink::Database.database.remove self.class.name, "WHERE `#{self.class.primary_key[0]}`=#{(pkvalue.is_a?(Numeric)) ? pkvalue : "\'#{pkvalue}\'"};"
222
223
  end
223
224
 
225
+ # Instance method
226
+ #
227
+ # Queries the database for foreign keys and attaches them to the
228
+ # matching foreign accessor
229
+ # [param foreign_class:] Defines the foreign class name or class
230
+ def find_references(foreign_class)
231
+ c = (foreign_class.is_a? Class) ? foreign_class : Ink::Model.classname(foreign_class)
232
+ relationship = self.class.foreign[c.class_name]
233
+ if relationship
234
+ result_array = (relationship == "many_many") ? Ink::Database.database.find_union(self.class, self.pk, c) : Ink::Database.database.find_references(self.class, self.pk, c)
235
+ instance_variable_set("@#{c.table_name}", (relationship =~ /_one$/) ? result_array[0] : result_array)
236
+ true
237
+ else
238
+ false
239
+ end
240
+ end
241
+
224
242
  # Class method
225
243
  #
226
244
  # This will create SQL statements for creating the
@@ -231,7 +249,7 @@ module Ink
231
249
  result = Array.new
232
250
  raise NotImplementedError.new("Cannot create a Database without field definitions") if not self.respond_to? :fields
233
251
 
234
- string = "CREATE TABLE #{Model::str_to_tablename(self.name)} ("
252
+ string = "CREATE TABLE #{self.table_name} ("
235
253
  mfk = self.foreign_key
236
254
  fields = self.fields
237
255
  for i in 0...fields.keys.length
@@ -246,11 +264,11 @@ module Ink
246
264
  for i in 0...foreign.keys.length
247
265
  k = foreign.keys[i]
248
266
  v = foreign[k]
249
- fk = Model::classname(k).foreign_key
267
+ fk = Ink::Model::classname(k).foreign_key
250
268
  string += ",`#{fk[0]}` #{fk[1]}" if fk.length > 0 and (v == "one_many" or (v == "one_one" and (self.name <=> k) < 0))
251
269
 
252
270
  if mfk.length > 0 and fk.length > 1 and v == "many_many" and (self.name <=> k) < 0
253
- result.push "CREATE TABLE #{Model::str_to_tablename(self.name)}_#{Model::str_to_tablename(k)} (#{Ink::Database.database.primary_key_autoincrement*" "}, `#{mfk[0]}` #{mfk[1]}, `#{fk[0]}` #{fk[1]});"
271
+ result.push "CREATE TABLE #{self.table_name}_#{Ink::Model::str_to_tablename(k)} (#{Ink::Database.database.primary_key_autoincrement*" "}, `#{mfk[0]}` #{mfk[1]}, `#{fk[0]}` #{fk[1]});"
254
272
  end
255
273
  end
256
274
  end
@@ -259,6 +277,22 @@ module Ink
259
277
  result
260
278
  end
261
279
 
280
+ # Class method
281
+ #
282
+ # This will retrieve a string-representation of the model name
283
+ # [returns:] valid classname
284
+ def self.class_name
285
+ self.name
286
+ end
287
+
288
+ # Class method
289
+ #
290
+ # This will retrieve a tablename-representation of the model name
291
+ # [returns:] valid tablename
292
+ def self.table_name
293
+ self.str_to_tablename self.name
294
+ end
295
+
262
296
  # Class method
263
297
  #
264
298
  # This will check the parent module for existing classnames
@@ -266,7 +300,11 @@ module Ink
266
300
  # [param str:] some string
267
301
  # [returns:] valid classname or nil
268
302
  def self.str_to_classname(str)
269
- ((Module.const_get str.capitalize).is_a? Class) ? str.capitalize : nil
303
+ res = []
304
+ str.scan(/((^|_)([a-z0-9]+))/) { |s|
305
+ res.push(s[2][0].upcase + ((s[2].length > 1) ? s[2][1,s[2].length] : "")) if s.length > 0
306
+ }
307
+ ((Module.const_get res.join).is_a? Class) ? res.join : nil
270
308
  end
271
309
 
272
310
  # Class method
@@ -277,7 +315,11 @@ module Ink
277
315
  # [param str:] some string
278
316
  # [returns:] valid tablename or nil
279
317
  def self.str_to_tablename(str)
280
- ((Module.const_get str.capitalize).is_a? Class) ? str.downcase : nil
318
+ res = []
319
+ str.scan(/([A-Z][a-z0-9]*)/) { |s|
320
+ res.push (res.length>0) ? "_" + s.join.downcase : s.join.downcase
321
+ }
322
+ ((Module.const_get str).is_a? Class) ? res.join : nil
281
323
  end
282
324
 
283
325
  # Class method
@@ -288,7 +330,15 @@ module Ink
288
330
  # [param str:] some string
289
331
  # [returns:] valid class or nil
290
332
  def self.classname(str)
291
- ((Module.const_get str.capitalize).is_a? Class) ? (Module.const_get str.capitalize) : nil
333
+ res = []
334
+ if str[0] =~ /^[a-z]/
335
+ str.scan(/((^|_)([a-z0-9]+))/) { |s|
336
+ res.push(s[2][0].upcase + ((s[2].length > 1) ? s[2][1,s[2].length] : "")) if s.length > 0
337
+ }
338
+ else
339
+ res.push str
340
+ end
341
+ ((Module.const_get res.join).is_a? Class) ? (Module.const_get res.join) : nil
292
342
  end
293
343
 
294
344
  # Class method
@@ -317,7 +367,7 @@ module Ink
317
367
  # [returns:] Array of the form: key name, key type or empty
318
368
  def self.foreign_key
319
369
  pk = self.primary_key
320
- return (pk) ? ["#{self.str_to_tablename(self.name)}_#{pk[0]}", pk[1]] : []
370
+ return (pk) ? ["#{self.table_name}_#{pk[0]}", pk[1]] : []
321
371
  end
322
372
 
323
373
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: webink
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.2.9
5
+ version: 1.3.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Matthias Geier
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-08-25 00:00:00 Z
13
+ date: 2012-09-14 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: fcgi
@@ -51,7 +51,7 @@ files:
51
51
  - lib/webink/controller.rb
52
52
  - bin/webink_database
53
53
  - bin/rfcgi
54
- homepage: http://powerpuff.net/
54
+ homepage: https://github.com/matthias-geier/WebInk
55
55
  licenses: []
56
56
 
57
57
  post_install_message: