webink 1.3.3 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/webink/database.rb +67 -48
  2. data/lib/webink/model.rb +166 -103
  3. metadata +3 -3
@@ -1,9 +1,9 @@
1
1
  module Ink
2
2
 
3
3
  # = Database class
4
- #
4
+ #
5
5
  # == Config
6
- #
6
+ #
7
7
  # Currently there are two types of databases supported, MySQL and
8
8
  # SQLite3. Either way, you need to specify them in a config-file
9
9
  # that is located inside the web project folder.
@@ -39,6 +39,16 @@ module Ink
39
39
  # This is the most basic query, it returns an Array of results,
40
40
  # and each element contains a Hash of column_name => column_entry.
41
41
  #
42
+ # Ink::Database.database.query("SELECT * FROM x;", Array){ |itm, k, v|
43
+ # itm.push v
44
+ # }
45
+ #
46
+ # The query method has a second parameter "type" which defaults to Hash.
47
+ # This is the class instance created in the resultset array (i.e.
48
+ # query returns [ type, type, type,...]).
49
+ # A block allows you to assign the k (column name) and v (value) to itm
50
+ # (a type.new taken from the second parameter) however you like.
51
+ #
42
52
  # The following methods are convenience methods to access data for
43
53
  # models. As example a model Apple and its n:1 relation to Tree
44
54
  # are used. Please note that both class and database table name can
@@ -86,14 +96,14 @@ module Ink
86
96
  # This will return a date in the form of 2012-11-20 10:00:02 and takes a Time
87
97
  # instance.
88
98
  #
89
- #
99
+ #
90
100
  #
91
101
  class Database
92
102
  private_class_method :new
93
103
  @@database = nil
94
-
104
+
95
105
  # Private Constructor
96
- #
106
+ #
97
107
  # Uses the config parameter to create a database
98
108
  # connection, and will throw an error, if that is not
99
109
  # possible.
@@ -109,32 +119,32 @@ module Ink
109
119
  raise ArgumentError.new("Database undefined.")
110
120
  end
111
121
  end
112
-
122
+
113
123
  # Class method
114
- #
124
+ #
115
125
  # Instanciates a new Database if none is found
116
126
  # [param config:] Hash of config parameters
117
127
  def self.create(config)
118
128
  @@database = new(config) if not @@database
119
129
  end
120
-
130
+
121
131
  # Class method
122
- #
132
+ #
123
133
  # Removes an instanciated Database
124
134
  def self.drop
125
135
  @@database = nil if @@database
126
136
  end
127
-
137
+
128
138
  # Class method
129
- #
139
+ #
130
140
  # Returns the Database instance or raises a Runtime Error
131
141
  # [returns:] Database instance
132
142
  def self.database
133
143
  (@@database) ? @@database : (raise RuntimeError.new("No Database found. Create one first"))
134
144
  end
135
-
145
+
136
146
  # Instance method
137
- #
147
+ #
138
148
  # This will retrieve all tables nested into
139
149
  # the connected database.
140
150
  # [returns:] Array of tables
@@ -158,50 +168,59 @@ module Ink
158
168
  end
159
169
  result
160
170
  end
161
-
171
+
162
172
  # Instance method
163
- #
173
+ #
164
174
  # Send an SQL query string to the database
165
175
  # and retrieve a result set
166
176
  # [param query:] SQL query string
167
177
  # [returns:] Array of Hashes of column_name => column_entry
168
- def query(query)
178
+ def query(query, type=Hash)
179
+ type = Hash if not block_given?
169
180
  result = Array.new
170
181
  if @type == "mysql"
171
182
  re = @db.method("query").call query
172
183
  if re
173
184
  re.each_hash do |row|
174
- result.push Hash.new
185
+ result.push type.new
175
186
  row.each do |k,v|
176
187
  if v =~ /^[0-9]+$/
177
188
  v = $&.to_i
178
189
  elsif v =~ /^[0-9]+\.[0-9]+$/
179
190
  v = $&.to_f
180
191
  end
181
- result[result.length-1][k] = v
192
+ if block_given?
193
+ yield(result[result.length-1], k, v)
194
+ else
195
+ result[result.length-1][k] = v
196
+ end
182
197
  end
183
198
  end
184
199
  end
185
200
  elsif @type == "sqlite3"
186
201
  re = @db.method("query").call query
187
202
  re.each do |row|
188
- result.push Hash.new
189
- for i in 0...re.columns.length
203
+ result.push type.new
204
+ re.columns.each_index do |i|
190
205
  if row[i] =~ /^[0-9]+$/
191
206
  row[i] = $&.to_i
192
207
  elsif row[i] =~ /^[0-9]+\.[0-9]+$/
193
208
  row[i] = $&.to_f
194
209
  end
195
- result[result.length-1][re.columns[i]] = row[i]
210
+ if block_given?
211
+ yield(result[result.length-1], re.columns[i], row[i])
212
+ else
213
+ result[result.length-1][re.columns[i]] = row[i]
214
+ end
196
215
  end
197
216
  end
198
217
  re.close if not re.closed?
199
218
  end
200
219
  result
201
220
  end
202
-
221
+
203
222
  # Instance method
204
- #
223
+ #
205
224
  # Closes the database connection, there is no way
206
225
  # to reopen without creating a new Ink::Database instance
207
226
  def close
@@ -215,9 +234,9 @@ module Ink
215
234
  end
216
235
  self.class.drop
217
236
  end
218
-
237
+
219
238
  # Instance method
220
- #
239
+ #
221
240
  # Attempts to fetch the last inserted primary key
222
241
  # [param class_name:] Defines the __table__ name or class
223
242
  # [returns:] primary key or nil
@@ -229,9 +248,9 @@ module Ink
229
248
  response = self.query("SELECT MAX(#{pk_name}) as id FROM #{table_name};")
230
249
  return (response.length > 0) ? response[0]["id"] : nil
231
250
  end
232
-
251
+
233
252
  # Instance method
234
- #
253
+ #
235
254
  # Creates the SQL syntax for the chosen database type
236
255
  # to define a primary key, autoincrementing field
237
256
  # [returns:] SQL syntax for a primary key field
@@ -244,9 +263,9 @@ module Ink
244
263
  end
245
264
  result
246
265
  end
247
-
266
+
248
267
  # Instance method
249
- #
268
+ #
250
269
  # Delete something from the database.
251
270
  # [param class_name:] Defines the class name or class
252
271
  # [param params:] Additional SQL syntax like WHERE conditions (optional)
@@ -255,9 +274,9 @@ module Ink
255
274
  return if not table_name
256
275
  self.query("DELETE FROM #{table_name} #{params};")
257
276
  end
258
-
277
+
259
278
  # Instance method
260
- #
279
+ #
261
280
  # Retrieve class instances, that are loaded with the database result set.
262
281
  # [param class_name:] Defines the class name or class which should be queried
263
282
  # [param params:] Additional SQL syntax like WHERE conditions (optional)
@@ -267,7 +286,7 @@ module Ink
267
286
  result = Array.new
268
287
  table_name = c.table_name
269
288
  return result if not table_name
270
-
289
+
271
290
  re = self.query("SELECT * FROM #{table_name} #{params};")
272
291
  re.each do |entry|
273
292
  instance = c.new entry
@@ -275,9 +294,9 @@ module Ink
275
294
  end
276
295
  result
277
296
  end
278
-
297
+
279
298
  # Instance method
280
- #
299
+ #
281
300
  # Retrieve class2 instances, that are related to the class1 instance with
282
301
  # primary key class1_id. This is done via an additional relationship table.
283
302
  # Only relevant for many_many relationships.
@@ -308,9 +327,9 @@ module Ink
308
327
  end
309
328
  result
310
329
  end
311
-
330
+
312
331
  # Instance method
313
- #
332
+ #
314
333
  # Retrieve class2 instances, that are related to the class1 instance with
315
334
  # primary key class1_id. Not relevant for many_many relationships
316
335
  # [param class1:] Reference classname or class
@@ -336,16 +355,16 @@ module Ink
336
355
  else
337
356
  re = self.query "SELECT * FROM #{tablename2} WHERE #{fk1} = #{class1_id} #{params};"
338
357
  end
339
-
358
+
340
359
  re.each do |entry|
341
360
  instance = c2.new entry
342
361
  result.push instance
343
362
  end
344
363
  result
345
364
  end
346
-
365
+
347
366
  # Instance method
348
- #
367
+ #
349
368
  # Retrieve one class2 instance, that is related to the class1 instance with
350
369
  # primary key class1_id. Only relevant for one_one and one_many relationships
351
370
  # [param class1:] Reference classname or class
@@ -361,9 +380,9 @@ module Ink
361
380
  nil
362
381
  end
363
382
  end
364
-
383
+
365
384
  # Instance method
366
- #
385
+ #
367
386
  # This method attempts to remove all existing relationship data
368
387
  # of instance with link of type: type. For one_one relationships
369
388
  # this works only one way, requiring a second call later on before
@@ -392,9 +411,9 @@ module Ink
392
411
  @db.query "DELETE FROM #{union_class} WHERE #{instance.class.foreign_key[0]}=#{value};"
393
412
  end
394
413
  end
395
-
414
+
396
415
  # Instance method
397
- #
416
+ #
398
417
  # Attempt to create links of instance to the data inside value.
399
418
  # link is the class of the related data, and type refers to the
400
419
  # relationship type of the two. When one tries to insert an array
@@ -422,9 +441,9 @@ module Ink
422
441
  self.create_link instance, link, type, fk
423
442
  end
424
443
  end
425
-
444
+
426
445
  # Instance method
427
- #
446
+ #
428
447
  # Creates a link between instance and a link with primary fk.
429
448
  # The relationship between the two is defined by type. one_one
430
449
  # relationships are placing an additional call to delete_all_links
@@ -462,7 +481,7 @@ module Ink
462
481
  @db.query "INSERT INTO #{union_class} (#{instance.class.foreign_key[0]}, #{link.foreign_key[0]}) VALUES (#{value}, #{fk});"
463
482
  end
464
483
  end
465
-
484
+
466
485
  # Class method
467
486
  #
468
487
  # Formats a Time object according to the SQL TimeDate standard
@@ -471,7 +490,7 @@ module Ink
471
490
  def self.format_date(date)
472
491
  (date.instance_of? Time) ? date.strftime("%Y-%m-%d %H:%M:%S") : ""
473
492
  end
474
-
493
+
475
494
  end
476
-
495
+
477
496
  end
@@ -8,6 +8,7 @@ module Ink
8
8
  # class called Apple < Ink::Model
9
9
  #
10
10
  # apple = Apple.new {:color => "red", :diameter => 4}
11
+ # apple = Apple.new [ "red", 4 ]
11
12
  #
12
13
  # The constructor checks, if there are class methods 'fields'
13
14
  # and 'foreign' defined. If that check is positive, it will
@@ -15,6 +16,9 @@ module Ink
15
16
  # the database, and throw an exception if fields is lacking
16
17
  # an entry (excluded the primary key). The other case just
17
18
  # creates an Apple with the Hash as instance variables.
19
+ # An alternate method of creating a new apple is by providing
20
+ # an Array of values in the same order as in the fields
21
+ # definition.
18
22
  #
19
23
  # puts apple.color
20
24
  #
@@ -83,7 +87,7 @@ module Ink
83
87
  # many_many, many_one]
84
88
  # Obviously the Tree class requires a foreign with "Apple"
85
89
  # mapped to "many_one" to match this schema.
86
- #
90
+ #
87
91
  # You can override the automatically generated getters and
88
92
  # setters in any Model class you create by just redefining
89
93
  # the methods.
@@ -91,12 +95,13 @@ module Ink
91
95
  # == Convenience methods
92
96
  #
93
97
  # self.primary_key
98
+ # self.primary_key_type
94
99
  # self.foreign_key
100
+ # self.foreign_key_type
95
101
  #
96
- # Both return an Array of length 2, where the second entry
97
- # is the type and the first for primary_key is the name of
98
- # the primary key (default "id"). The foreign_key has a
99
- # combination of "classname"_"primary_key" (i.e. "apple_id")
102
+ # primary_key is the name of the primary key (default "id").
103
+ # The foreign_key has a combination of "classname"_"primary_key"
104
+ # (i.e. "apple_id")
100
105
  #
101
106
  # self.class_name
102
107
  #
@@ -118,89 +123,131 @@ module Ink
118
123
  #
119
124
  #
120
125
  class Model
121
-
126
+
122
127
  # Constructor
123
128
  #
124
129
  # Keys from the data parameter will be converted into
125
130
  # instance variables with getters and setters in place.
131
+ # The data parameter can be an Array of length of the
132
+ # defined fields or without the primary key. The order
133
+ # needs to be the same as the defined fields.
126
134
  # The primary key has no setter, but adds a getter called
127
135
  # pk for convenience.
128
- # [param data:] Hash of String => Objects
136
+ # [param data:] Hash of String => Objects or Array of Objects
129
137
  def initialize(data)
130
138
  if self.class.respond_to? :fields
139
+ i = 0
131
140
  self.class.fields.each do |k,v|
132
- raise NameError.new("Model cannot use #{k} as field, it is blocked by primary key") if k.to_s.downcase == "pk"
133
- raise LoadError.new("Model cannot be loaded, argument missing: #{k}") if not data.key?(k.to_s) and self.class.primary_key[0] != k
134
- entry = nil
135
- if data[k.to_s].nil?
136
- entry = nil
137
- elsif data[k.to_s].is_a? String
138
- entry = data[k.to_s].gsub(/'/, '&#39;')
139
- elsif data[k.to_s].is_a? Numeric
140
- entry = data[k.to_s]
141
+ if data.is_a? Array
142
+ raise LoadError.new("Model cannot be loaded, wrong number or arguments #{data.length} expected #{self.class.fields.length} or #{self.class.fields.length - 1}") if data.length < self.class.fields.length - 1 or data.length > self.class.fields.length
143
+ init_field k, data[i] if self.class.primary_key != k or data.length == self.class.fields.length
144
+ i += 1
141
145
  else
142
- entry = "\'#{data[k.to_s]}\'"
143
- end
144
- instance_variable_set("@#{k}", entry)
145
-
146
- if not self.respond_to? k
147
- self.class.send(:define_method, k) do
148
- instance_variable_get "@#{k}"
149
- end
150
- end
151
- if self.class.primary_key[0] != k
152
- if not self.respond_to? "#{k}="
153
- self.class.send(:define_method, "#{k}=") do |val|
154
- if data[k.to_s].nil?
155
- val = nil
156
- elsif val.is_a? String
157
- val = val.gsub(/'/, '&#39;')
158
- elsif val.is_a? Numeric
159
- val = val
160
- else
161
- val = "\'#{val}\'"
162
- end
163
- instance_variable_set "@#{k}", val
164
- end
165
- end
166
- else
167
- self.class.send(:define_method, "pk") do
168
- instance_variable_get "@#{k.to_s.downcase}"
169
- end
146
+ raise LoadError.new("Model cannot be loaded, argument missing: #{key}") if not data.key?(k.to_s) and self.class.primary_key != k
147
+ init_field k, data[k.to_s]
170
148
  end
171
149
  end
172
150
  if self.class.respond_to? :foreign
173
151
  self.class.foreign.each do |k,v|
174
- k_table = self.class.str_to_tablename(k)
175
- raise NameError.new("Model cannot use #{k_table} as foreign, it already exists") if k_table == "pk"
176
- if not self.respond_to? k_table
177
- instance_variable_set("@#{k_table}", nil)
178
- self.class.send(:define_method, k_table) do
179
- instance_variable_get "@#{k_table}"
180
- end
181
- self.class.send(:define_method, "#{k_table}=") do |val|
182
- instance_variable_set "@#{k_table}", val
183
- end
184
- end
152
+ init_foreign k
185
153
  end
186
154
  end
187
155
  else
188
156
  data.each do |k,v|
189
- entry = nil
190
- if v.nil?
191
- entry = nil
192
- elsif v.is_a? String
193
- entry = v.gsub(/'/, '&#39;')
194
- elsif v.is_a? Numeric
195
- entry = v
196
- else
197
- entry = "\'#{v}\'"
157
+ init_no_fields k, v
158
+ end
159
+ end
160
+ end
161
+
162
+ # Private instance method
163
+ #
164
+ # Provides an instance accessor and setter for the key. It is
165
+ # initialized with data[key].
166
+ # [key:] String
167
+ # [data:] Hash of String => Object
168
+ def init_field(key, value)
169
+ raise NameError.new("Model cannot use #{key} as field, it is blocked by primary key") if key.to_s.downcase == "pk"
170
+ entry = nil
171
+ if value.nil?
172
+ entry = nil
173
+ elsif value.is_a? String
174
+ entry = value.gsub(/'/, '&#39;')
175
+ elsif value.is_a? Numeric
176
+ entry = value
177
+ else
178
+ entry = "\'#{value}\'"
179
+ end
180
+ instance_variable_set("@#{key}", entry)
181
+
182
+ if not self.respond_to? key
183
+ self.class.send(:define_method, key) do
184
+ instance_variable_get "@#{key}"
185
+ end
186
+ end
187
+ if self.class.primary_key != key
188
+ if not self.respond_to? "#{key}="
189
+ self.class.send(:define_method, "#{key}=") do |val|
190
+ if val.nil?
191
+ val = nil
192
+ elsif val.is_a? String
193
+ val = val.gsub(/'/, '&#39;')
194
+ elsif val.is_a? Numeric
195
+ val = val
196
+ else
197
+ val = "\'#{val}\'"
198
+ end
199
+ instance_variable_set "@#{key}", val
198
200
  end
199
- instance_variable_set "@#{k}", entry
201
+ end
202
+ else
203
+ self.class.send(:define_method, "pk") do
204
+ instance_variable_get "@#{key.to_s.downcase}"
205
+ end
206
+ end
207
+ end
208
+ private :init_field
209
+
210
+ # Private instance method
211
+ #
212
+ # Evaluates the value type and provides an instance accessor
213
+ # to access the value by key.
214
+ # [key:] String
215
+ # [value:] Object
216
+ def init_no_fields(key, value)
217
+ entry = nil
218
+ if value.nil?
219
+ entry = nil
220
+ elsif value.is_a? String
221
+ entry = value.gsub(/'/, '&#39;')
222
+ elsif value.is_a? Numeric
223
+ entry = value
224
+ else
225
+ entry = "\'#{value}\'"
226
+ end
227
+ instance_variable_set "@#{key}", entry
228
+ end
229
+ private :init_no_fields
230
+
231
+ # Private instance method
232
+ #
233
+ # Transforms the key to tablename and provides an instance accessor
234
+ # and setter for the key. It is initialized with nil.
235
+ # [key:] String
236
+ def init_foreign(key)
237
+ k_table = self.class.str_to_tablename(key)
238
+ raise NameError.new("Model cannot use #{k_table} as foreign, it already exists") if k_table == "pk"
239
+ if not self.respond_to?(k_table)
240
+ instance_variable_set("@#{k_table}", nil)
241
+ self.class.send(:define_method, k_table) do
242
+ instance_variable_get "@#{k_table}"
243
+ end
244
+ self.class.send(:define_method, "#{k_table}=") do |val|
245
+ instance_variable_set "@#{k_table}", val
200
246
  end
201
247
  end
202
248
  end
203
-
249
+ private :init_foreign
250
+
204
251
  # Instance method
205
252
  #
206
253
  # Save the instance to the database. Set all foreign sets to
@@ -235,7 +282,7 @@ module Ink
235
282
  instance_variable_set "@#{self.class.primary_key[0]}", pk.is_a?(Numeric) ? pk : "\'#{pk}\'" if pk
236
283
  end
237
284
  end
238
-
285
+
239
286
  if self.class.respond_to? :foreign
240
287
  self.class.foreign.each do |k,v|
241
288
  value = instance_variable_get "@#{self.class.str_to_tablename(k)}"
@@ -246,9 +293,9 @@ module Ink
246
293
  end
247
294
  end
248
295
  end
249
-
296
+
250
297
  # Instance method
251
- #
298
+ #
252
299
  # Deletes the data from the database, essentially making the instance
253
300
  # obsolete. Disregard from using the instance anymore.
254
301
  # All links between models will be removed also.
@@ -259,11 +306,11 @@ module Ink
259
306
  Ink::Database.database.delete_all_links self, Ink::Model.classname(k), v
260
307
  end
261
308
  end
262
-
309
+
263
310
  pkvalue = instance_variable_get "@#{self.class.primary_key[0]}"
264
311
  Ink::Database.database.remove self.class.name, "WHERE `#{self.class.primary_key[0]}`=#{(pkvalue.is_a?(Numeric)) ? pkvalue : "\'#{pkvalue}\'"}"
265
312
  end
266
-
313
+
267
314
  # Instance method
268
315
  #
269
316
  # Queries the database for foreign keys and attaches them to the
@@ -280,9 +327,9 @@ module Ink
280
327
  false
281
328
  end
282
329
  end
283
-
330
+
284
331
  # Class method
285
- #
332
+ #
286
333
  # This will create SQL statements for creating the
287
334
  # database tables. 'fields' method is mandatory for
288
335
  # this, and 'foreign' is optional.
@@ -290,7 +337,7 @@ module Ink
290
337
  def self.create
291
338
  result = Array.new
292
339
  raise NotImplementedError.new("Cannot create a Database without field definitions") if not self.respond_to? :fields
293
-
340
+
294
341
  string = "CREATE TABLE #{self.table_name} ("
295
342
  mfk = self.foreign_key
296
343
  fields = self.fields
@@ -300,7 +347,7 @@ module Ink
300
347
  string += "#{Ink::Database.database.primary_key_autoincrement(k)*" "}" if k == self.primary_key[0]
301
348
  string += "," if i < fields.keys.length - 1
302
349
  end
303
-
350
+
304
351
  if self.respond_to? :foreign
305
352
  foreign = self.foreign
306
353
  for i in 0...foreign.keys.length
@@ -308,7 +355,7 @@ module Ink
308
355
  v = foreign[k]
309
356
  fk = Ink::Model::classname(k).foreign_key
310
357
  string += ",`#{fk[0]}` #{fk[1]}" if fk.length > 0 and (v == "one_many" or (v == "one_one" and (self.name <=> k) < 0))
311
-
358
+
312
359
  if mfk.length > 0 and fk.length > 1 and v == "many_many" and (self.name <=> k) < 0
313
360
  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]});"
314
361
  end
@@ -318,25 +365,25 @@ module Ink
318
365
  result.push string
319
366
  result
320
367
  end
321
-
368
+
322
369
  # Class method
323
- #
370
+ #
324
371
  # This will retrieve a string-representation of the model name
325
372
  # [returns:] valid classname
326
373
  def self.class_name
327
374
  self.name
328
375
  end
329
-
376
+
330
377
  # Class method
331
- #
378
+ #
332
379
  # This will retrieve a tablename-representation of the model name
333
380
  # [returns:] valid tablename
334
381
  def self.table_name
335
382
  self.str_to_tablename self.name
336
383
  end
337
-
384
+
338
385
  # Class method
339
- #
386
+ #
340
387
  # This will check the parent module for existing classnames
341
388
  # that match the input of the str parameter.
342
389
  # [param str:] some string
@@ -348,9 +395,9 @@ module Ink
348
395
  }
349
396
  ((Module.const_get res.join).is_a? Class) ? res.join : nil
350
397
  end
351
-
398
+
352
399
  # Class method
353
- #
400
+ #
354
401
  # This will check the parent module for existing classnames
355
402
  # that match the input of the str parameter. Once found, it
356
403
  # converts the string into the matching tablename.
@@ -363,9 +410,9 @@ module Ink
363
410
  }
364
411
  ((Module.const_get str).is_a? Class) ? res.join : nil
365
412
  end
366
-
413
+
367
414
  # Class method
368
- #
415
+ #
369
416
  # This will check the parent module for existing classnames
370
417
  # that match the input of the str parameter. Once found, it
371
418
  # returns the class, not the string of the class.
@@ -382,36 +429,52 @@ module Ink
382
429
  end
383
430
  ((Module.const_get res.join).is_a? Class) ? (Module.const_get res.join) : nil
384
431
  end
385
-
432
+
386
433
  # Class method
387
434
  #
388
435
  # This will find the primary key, as defined in the fields class
389
436
  # method.
390
- # [returns:] Array of the form: key name, key type or empty
437
+ # [returns:] key name or nil
391
438
  def self.primary_key
392
439
  if self.respond_to? :fields
393
- pk = nil
394
- pktype = nil
395
- self.fields.each do |k,v|
396
- if v.is_a?(String) and v == "PRIMARY KEY"
397
- pk = k
398
- pktype = Ink::Database.database.primary_key_autoincrement(k)[1]
399
- end
400
- end
401
- return [pk, pktype]
440
+ field = self.fields.select{|k,v| v.is_a?(String) and v == "PRIMARY KEY"}
441
+ return field.keys.first
402
442
  end
403
- return []
443
+ nil
404
444
  end
405
-
445
+
446
+ # Class method
447
+ #
448
+ # This will find the primary key type, as defined in the fields
449
+ # class method.
450
+ # [returns:] key type or nil
451
+ def self.primary_key_type
452
+ if self.respond_to? :fields
453
+ field = self.fields.select{|k,v| v.is_a?(String) and v == "PRIMARY KEY"}
454
+ return Ink::Database.database.
455
+ primary_key_autoincrement(field.keys.first)[1]
456
+ end
457
+ nil
458
+ end
459
+
406
460
  # Class method
407
461
  #
408
462
  # This will create the foreign key from the defined primary key
409
- # [returns:] Array of the form: key name, key type or empty
463
+ # [returns:] key name or nil
410
464
  def self.foreign_key
411
465
  pk = self.primary_key
412
- return (pk) ? ["#{self.table_name}_#{pk[0]}", pk[1]] : []
466
+ return (pk) ? "#{self.table_name}_#{pk}" : nil
467
+ end
468
+
469
+ # Class method
470
+ #
471
+ # This will find the foreign key type, taken from the primary key
472
+ # in fields.
473
+ # [returns:] key type or nil
474
+ def self.foreign_key_type
475
+ self.primary_key_type
413
476
  end
414
-
477
+
415
478
  end
416
-
479
+
417
480
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webink
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: '2.0'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-19 00:00:00.000000000 Z
12
+ date: 2013-03-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fcgi
@@ -52,10 +52,10 @@ extensions: []
52
52
  extra_rdoc_files: []
53
53
  files:
54
54
  - lib/webink.rb
55
- - lib/webink/controller.rb
56
55
  - lib/webink/database.rb
57
56
  - lib/webink/beauty.rb
58
57
  - lib/webink/model.rb
58
+ - lib/webink/controller.rb
59
59
  - bin/rfcgi
60
60
  - bin/webink_database
61
61
  homepage: https://github.com/matthias-geier/WebInk