webink 1.3.3 → 2.0
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.
- data/lib/webink/database.rb +67 -48
- data/lib/webink/model.rb +166 -103
- metadata +3 -3
data/lib/webink/database.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
189
|
-
|
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
|
-
|
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
|
data/lib/webink/model.rb
CHANGED
@@ -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
|
-
#
|
97
|
-
#
|
98
|
-
#
|
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
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
entry = nil
|
137
|
-
elsif data[k.to_s].is_a? String
|
138
|
-
entry = data[k.to_s].gsub(/'/, ''')
|
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
|
-
|
143
|
-
|
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(/'/, ''')
|
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
|
-
|
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
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
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(/'/, ''')
|
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(/'/, ''')
|
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
|
-
|
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(/'/, ''')
|
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:]
|
437
|
+
# [returns:] key name or nil
|
391
438
|
def self.primary_key
|
392
439
|
if self.respond_to? :fields
|
393
|
-
|
394
|
-
|
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
|
-
|
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:]
|
463
|
+
# [returns:] key name or nil
|
410
464
|
def self.foreign_key
|
411
465
|
pk = self.primary_key
|
412
|
-
return (pk) ?
|
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:
|
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-
|
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
|