webink 2.0 → 2.0.1

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/bin/rfcgi CHANGED
@@ -1,3 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
1
3
  require "fcgi"
2
4
  require "simple_mmap"
3
5
  require "webink/beauty"
@@ -43,7 +45,7 @@ FCGI.each_cgi do |cgi|
43
45
  control = eval fhandle.read_window_data(0,fhandle.size), getBinding(cgi,cgi.env_table,control) if fhandle
44
46
  fhandle.close
45
47
  raise StandardError.new("Routes not matched.") if control.keys.length <= 1
46
-
48
+
47
49
  control[:get] = pram
48
50
  control[:config] = Ink::Beauty.load_config script
49
51
  control[:time] = time
@@ -70,13 +72,13 @@ FCGI.each_cgi do |cgi|
70
72
  else
71
73
  cgi.params = pram
72
74
  end
73
-
75
+
74
76
  script = Ink::Beauty.load_init script
75
77
  fhandle = SimpleMmap::MappedFile.new(script)
76
78
  Dir.chdir( File.dirname(script) )
77
79
  eval fhandle.read_window_data(0,fhandle.size), getBinding(cgi,cgi.env_table,control) if fhandle
78
80
  fhandle.close
79
-
81
+
80
82
  rescue LoadError => bang
81
83
  if is_production
82
84
  puts cgi.header({"Location" => "/status-404.html"}) if use_errors
@@ -85,7 +87,7 @@ FCGI.each_cgi do |cgi|
85
87
  puts cgi.header
86
88
  puts "<hr><b>LoadError:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
87
89
  end
88
-
90
+
89
91
  rescue NotImplementedError => bang
90
92
  if is_production
91
93
  puts cgi.header({"Location" => "/status-500.html"}) if use_errors
@@ -94,7 +96,7 @@ FCGI.each_cgi do |cgi|
94
96
  puts cgi.header
95
97
  puts "<hr><b>NotImplementedError:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
96
98
  end
97
-
99
+
98
100
  rescue ArgumentError => bang
99
101
  if is_production
100
102
  puts cgi.header({"Location" => "/status-500.html"}) if use_errors
@@ -103,7 +105,7 @@ FCGI.each_cgi do |cgi|
103
105
  puts cgi.header
104
106
  puts "<hr><b>ArgumentError:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
105
107
  end
106
-
108
+
107
109
  rescue RuntimeError => bang
108
110
  if is_production
109
111
  puts cgi.header({"Location" => "/status-500.html"}) if use_errors
@@ -112,7 +114,7 @@ FCGI.each_cgi do |cgi|
112
114
  puts cgi.header
113
115
  puts "<hr><b>RuntimeError:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
114
116
  end
115
-
117
+
116
118
  rescue NameError => bang
117
119
  if is_production
118
120
  puts cgi.header({"Location" => "/status-500.html"}) if use_errors
@@ -121,7 +123,7 @@ FCGI.each_cgi do |cgi|
121
123
  puts cgi.header
122
124
  puts "<hr><b>NameError:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
123
125
  end
124
-
126
+
125
127
  rescue Exception, StandardError => bang
126
128
  if is_production
127
129
  puts cgi.header({"Location" => "/status-500.html"}) if use_errors
@@ -131,7 +133,7 @@ FCGI.each_cgi do |cgi|
131
133
  puts "<hr><b>Exception:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
132
134
  end
133
135
  end
134
-
136
+
135
137
  script = nil
136
138
  fhandle = nil
137
139
  control = nil
@@ -1,3 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
1
3
  require 'simple_mmap'
2
4
  require 'webink/beauty'
3
5
 
@@ -23,7 +25,7 @@ begin
23
25
  Ink::Database.create config
24
26
  db = Ink::Database.database
25
27
  db_tables = db.tables
26
-
28
+
27
29
  if ARGV[0] == "drop"
28
30
  puts "Dropping old tables..."
29
31
  db_tables.each do |t|
@@ -31,7 +33,7 @@ begin
31
33
  db.query "DROP TABLE #{t};"
32
34
  end
33
35
  end
34
-
36
+
35
37
  puts "Creating new tables..."
36
38
  model_classes.each do |m|
37
39
  puts "...for class: #{m.name}:"
@@ -1,20 +1,20 @@
1
1
  module Ink
2
2
 
3
3
  # = Controller class
4
- #
4
+ #
5
5
  # == Usage
6
- #
6
+ #
7
7
  # Controllers handle incoming requests and decide what to do
8
8
  # with them. A controller has access to all incoming data, like
9
9
  # POST and GET (through @params[:get] and @params[:post] as
10
10
  # well as the config.
11
11
  #
12
12
  # class App < Ink::Controller
13
- #
13
+ #
14
14
  # def index
15
15
  # redirect_to :controller => "my_app", :module => "feed", :id => 29382374
16
16
  # end
17
- #
17
+ #
18
18
  # def feed
19
19
  # @arg = @params[:id]
20
20
  # @users = []
@@ -25,14 +25,12 @@ module Ink
25
25
  # @arg = "foo bar"
26
26
  # render :partial => "part", :standalone => true
27
27
  # end
28
- #
28
+ #
29
29
  # end
30
30
  #
31
- # A controller named App should have the filename app.rb (note
32
- # that underscores are not allowed: "app".capitalize must be
33
- # the loadable classname) and be placed inside the project
34
- # controller folder. It can have instance methods that are
35
- # usually refered to as modules.
31
+ # A controller named App should have the filename app.rb and be
32
+ # placed inside the project controller folder. It can have
33
+ # instance methods that are usually refered to as modules.
36
34
  # So a route should contain at least a :controller and a :module.
37
35
  #
38
36
  # In the sample above there are three modules, index redirects
@@ -51,7 +49,8 @@ module Ink
51
49
  # == Templates
52
50
  #
53
51
  # All templates are to be put into the project views folder, and are
54
- # to be named name.html.erb, while partials are to be named _anothername.html.erb.
52
+ # to be named name.html.erb, while partials are to be named
53
+ # _anothername.html.erb.
55
54
  # It is possible to create subfolders and call the templates via
56
55
  # :template => "subfolder/template.html.erb".
57
56
  #
@@ -81,16 +80,19 @@ module Ink
81
80
  # [ /^\/?$/, {:controller => "app", :module => "index"} ],
82
81
  # ]
83
82
  #
84
- # Routes are built as a priority list, the first match will be the route taken. All
85
- # route configurations must include a variable named root, as it will help to create
86
- # dynamic links within websites. Root is relative to the webserver root. Assume your
87
- # webserver points to public_html, then routes can be "" for the public_html folder,
88
- # or "/anysubfolder" which points to anysubfolder. Deeper structures work too.
83
+ # Routes are built as a priority list, the first match will be the
84
+ # route taken. All route configurations must include a variable
85
+ # named root, as it will help to create dynamic links within
86
+ # websites. Root is relative to the webserver root. Assume your
87
+ # webserver points to public_html, then routes can be "" for the
88
+ # public_html folder, or "/anysubfolder" which points to anysubfolder.
89
+ # Deeper structures work too.
89
90
  #
90
91
  # == Linking
91
92
  #
92
- # A controller has the ability to create hyperlinks for you, that will dynamically match
93
- # the project path etc. (and is also using the root variable from the routes.rb)
93
+ # A controller has the ability to create hyperlinks for you, that
94
+ # will dynamically match the project path etc. (and is also using
95
+ # the root variable from the routes.rb)
94
96
  #
95
97
  # link_to "name", "controller", "module", "param1", "param2", {:class => "h1", :id => "14"}
96
98
  #
@@ -99,14 +101,15 @@ module Ink
99
101
  # <a class="h1" id="14" href="/controller/module/param1/param2/">name</a>
100
102
  #
101
103
  # So the first entry of the argument array is the hyperlink name, then all
102
- # following entries are connected as the href string, prefixed by the root variable
103
- # that is set in the routes.rb. The hash includes the attributes for the <a>-tag.
104
+ # following entries are connected as the href string, prefixed by the root
105
+ # variable that is set in the routes.rb. The hash includes the attributes
106
+ # for the <a>-tag.
104
107
  #
105
108
  # == Pathing
106
109
  #
107
- # A controller also constructs paths for you (and is also using the root variable
108
- # from the routes.rb), which you can use to dynamically reroute forms, just to
109
- # mention one example.
110
+ # A controller also constructs paths for you (and is also using the root
111
+ # variable from the routes.rb), which you can use to dynamically reroute
112
+ # forms, just to mention one example.
110
113
  #
111
114
  # @my = "no"
112
115
  # path_to "this", "is", @my, "path"
@@ -119,42 +122,44 @@ module Ink
119
122
  #
120
123
  # == Sessions
121
124
  #
122
- # Usually very important in the development of websites are sessions. There is some
123
- # basic support for it in webink, that will make certain bits easier. For more information
124
- # have a look at the blog-demo.
125
+ # Usually very important in the development of websites are sessions.
126
+ # There is some basic support for it in webink, that will make certain
127
+ # bits easier. For more information have a look at the blog-demo.
128
+ #
129
+ # Each controller usually expects cookies to work, if you handle
130
+ # sessions via cgi. Whenever cookies do not work, or you do not
131
+ # intend to use them in the first place, path_to and link_to watch
132
+ # out for the instance variables @session_key and @session_id
133
+ # which are added via GET to the path/hyperlink, that they construct.
134
+ # Therefore the tools should not be used for external linking. The
135
+ # dispatcher automatically filters the GET session_id when using
136
+ # POST and adds it to the cgi.params, so sessions can be used confortably.
125
137
  #
126
- # Each controller usually expects cookies to work, if you handle sessions via cgi.
127
- # Whenever cookies do not work, or you do not intend to use them in the first place,
128
- # path_to and link_to watch out for the instance variables @session_key and @session_id
129
- # which are added via GET to the path/hyperlink, that they construct. Therefore the
130
- # tools should not be used for external linking. The dispatcher automatically filters
131
- # the GET session_id when using POST and adds it to the cgi.params, so sessions can
132
- # be used confortably.
138
+ # Per default, the @session_key should be "_session_id" as specified
139
+ # in the cgi/session library from ruby core, but the controller offers
140
+ # some freedom, in case you may want a different key name for some reason.
133
141
  #
134
- # Per default, the @session_key should be "_session_id" as specified in the cgi/session
135
- # library from ruby core, but the controller offers some freedom, in case you may want
136
- # a different key name for some reason.
137
142
  #
138
- #
139
143
  #
140
144
  class Controller
141
-
145
+
142
146
  # Constructor
143
- #
144
- # Creates a new controller of the derived class. params are the globals set
145
- # by the dispatcher, and include keys like: :get, :post and :config. Also the
146
- # matched routes are put there, :controller, :module and any parameters like
147
- # :id or :page that were retrieved from the routes.
147
+ #
148
+ # Creates a new controller of the derived class. params are the globals
149
+ # set by the dispatcher, and include keys like: :get, :post and :config.
150
+ # Also the matched routes are put there, :controller, :module and any
151
+ # parameters like :id or :page that were retrieved from the routes.
148
152
  # [param params:] Hash of Symbol => Objects
149
153
  def initialize(params)
150
154
  @params = params
151
155
  end
152
-
156
+
153
157
  # Instance method
154
- #
155
- # Render a template or a partial that is located in the ./views/ folder of the
156
- # project. Subfolders are allowed to be specified. All instance variables are
157
- # accessible from within the template, as are any instance methods.
158
+ #
159
+ # Render a template or a partial that is located in the ./views/ folder
160
+ # of the project. Subfolders are allowed to be specified. All instance
161
+ # variables are accessible from within the template, as are any instance
162
+ # methods.
158
163
  # [param args:] Hash of arguments
159
164
  # [returns:] interpreted erb instance or nil
160
165
  def render(args)
@@ -180,9 +185,9 @@ module Ink
180
185
  nil
181
186
  end
182
187
  end
183
-
188
+
184
189
  # Instance method
185
- #
190
+ #
186
191
  # Redirect to a controller and module. The new controller will
187
192
  # be instanciated with a copy of the current params.
188
193
  # [param args:] Hash of arguments
@@ -202,7 +207,7 @@ module Ink
202
207
  nil
203
208
  end
204
209
  end
205
-
210
+
206
211
  # Instance method
207
212
  #
208
213
  # Creates a dynamic hyperlink
@@ -230,7 +235,7 @@ module Ink
230
235
  href += "?#{@session_key}=#{@session_id}" if @session_id and @session_key
231
236
  "#{a}href=\"#{href}\">#{name}</a>"
232
237
  end
233
-
238
+
234
239
  # Instance method
235
240
  #
236
241
  # Creates a dynamic path
@@ -241,7 +246,7 @@ module Ink
241
246
  # [returns:] path
242
247
  def path_to(*args)
243
248
  href = (@params[:root].length == 0) ? "/" : "#{@params[:root]}#{(@params[:root][@params[:root].length-1].chr == "/") ? "" : "/"}"
244
-
249
+
245
250
  if args.is_a? Array
246
251
  for i in 0...args.length
247
252
  arg = args[i]
@@ -253,18 +258,18 @@ module Ink
253
258
  href += "?#{@session_key}=#{@session_id}" if @session_id and @session_key
254
259
  href
255
260
  end
256
-
261
+
257
262
  # Instance method
258
- #
263
+ #
259
264
  # Retrieve the current binding of the instance.
260
265
  # [param locals:] an Array of data for the template
261
266
  # [returns:] current binding
262
267
  def getBinding(locals)
263
268
  binding
264
269
  end
265
-
270
+
266
271
  # Class method
267
- #
272
+ #
268
273
  # Retrieve the class of the name controller, that can be instanciated
269
274
  # by using new. Raises a NameError.
270
275
  # [param controller:] Controller name string
@@ -279,9 +284,9 @@ module Ink
279
284
  end
280
285
  ((Module.const_get controller.capitalize).is_a? Class) ? (Module.const_get controller.capitalize) : (raise NameError.new("Controller not found."))
281
286
  end
282
-
287
+
283
288
  # Instance method
284
- #
289
+ #
285
290
  # Retrieve the method of name mod, that can be called by using the
286
291
  # call method. Raises a NameError.
287
292
  # [param mod:] Method name string
@@ -289,7 +294,7 @@ module Ink
289
294
  def verify(mod)
290
295
  self.method(mod)
291
296
  end
292
-
297
+
293
298
  end
294
-
299
+
295
300
  end
@@ -188,6 +188,8 @@ module Ink
188
188
  v = $&.to_i
189
189
  elsif v =~ /^[0-9]+\.[0-9]+$/
190
190
  v = $&.to_f
191
+ elsif v =~ /^NULL$/
192
+ v = nil
191
193
  end
192
194
  if block_given?
193
195
  yield(result[result.length-1], k, v)
@@ -206,6 +208,8 @@ module Ink
206
208
  row[i] = $&.to_i
207
209
  elsif row[i] =~ /^[0-9]+\.[0-9]+$/
208
210
  row[i] = $&.to_f
211
+ elsif row[i] =~ /^NULL$/
212
+ row[i] = nil
209
213
  end
210
214
  if block_given?
211
215
  yield(result[result.length-1], re.columns[i], row[i])
@@ -241,12 +245,12 @@ module Ink
241
245
  # [param class_name:] Defines the __table__ name or class
242
246
  # [returns:] primary key or nil
243
247
  def last_inserted_pk(class_name)
244
- c = (class_name.is_a? Class) ? class_name : Ink::Model.classname(class_name)
245
- table_name = c.table_name
246
- pk_name = c.primary_key[0]
247
- return if not (table_name and pk_name)
248
+ class_name = Ink::Model.classname(class_name) unless class_name.is_a? Class
249
+ table_name = class_name.table_name
250
+ pk_name = class_name.primary_key
251
+ return if table_name.nil? or pk_name.nil?
248
252
  response = self.query("SELECT MAX(#{pk_name}) as id FROM #{table_name};")
249
- return (response.length > 0) ? response[0]["id"] : nil
253
+ return (response.empty?) ? nil : response.first["id"]
250
254
  end
251
255
 
252
256
  # Instance method
@@ -271,7 +275,7 @@ module Ink
271
275
  # [param params:] Additional SQL syntax like WHERE conditions (optional)
272
276
  def remove(class_name, params="")
273
277
  table_name = (class_name.is_a? Class) ? class_name.table_name : Ink::Model.str_to_tablename(class_name)
274
- return if not table_name
278
+ return if table_name.nil?
275
279
  self.query("DELETE FROM #{table_name} #{params};")
276
280
  end
277
281
 
@@ -282,14 +286,14 @@ module Ink
282
286
  # [param params:] Additional SQL syntax like WHERE conditions (optional)
283
287
  # [returns:] Array of class_name instances from the SQL result set
284
288
  def find(class_name, params="")
285
- c = (class_name.is_a? Class) ? class_name : Ink::Model.classname(class_name)
289
+ class_name = Ink::Model.classname(class_name) unless class_name.is_a? Class
286
290
  result = Array.new
287
- table_name = c.table_name
288
- return result if not table_name
291
+ table_name = class_name.table_name
292
+ return result if table_name.nil?
289
293
 
290
294
  re = self.query("SELECT * FROM #{table_name} #{params};")
291
295
  re.each do |entry|
292
- instance = c.new entry
296
+ instance = class_name.new entry
293
297
  result.push instance
294
298
  end
295
299
  result
@@ -306,23 +310,25 @@ module Ink
306
310
  # [param params:] Additional SQL syntax like GROUP BY (optional)
307
311
  # [returns:] Array of class2 instances from the SQL result set
308
312
  def find_union(class1, class1_id, class2, params="")
309
- c1 = (class1.is_a? Class) ? class1 : Ink::Model.classname(class1)
310
- c2 = (class2.is_a? Class) ? class2 : Ink::Model.classname(class2)
313
+ class1 = Ink::Model.classname(class1) unless class1.is_a? Class
314
+ class2 = Ink::Model.classname(class2) unless class2.is_a? Class
311
315
  result = Array.new
312
316
  relationship = nil
313
- c1.foreign.each do |k,v|
314
- relationship = v if k.downcase == c2.class_name.downcase
317
+ class1.foreign.each do |k,v|
318
+ relationship = v if k == class2.class_name
315
319
  end
316
320
  return result if relationship != "many_many"
317
- fk1 = c1.foreign_key[0]
318
- pk2 = c2.primary_key[0]
319
- fk2 = c2.foreign_key[0]
320
- tablename1 = c1.table_name
321
- tablename2 = c2.table_name
322
- union_class = ((c1.class_name.downcase <=> c2.class_name.downcase) < 0) ? "#{tablename1}_#{tablename2}" : "#{tablename2}_#{tablename1}"
321
+ fk1 = class1.foreign_key
322
+ pk2 = class2.primary_key
323
+ fk2 = class2.foreign_key
324
+ tablename1 = class1.table_name
325
+ tablename2 = class2.table_name
326
+ union_class = ((class1.class_name <=> class2.class_name) < 0) ?
327
+ "#{tablename1}_#{tablename2}" :
328
+ "#{tablename2}_#{tablename1}"
323
329
  re = self.query("SELECT #{tablename2}.* FROM #{union_class}, #{tablename2} WHERE #{union_class}.#{fk1} = #{class1_id} AND #{union_class}.#{fk2} = #{tablename2}.#{pk2} #{params};")
324
330
  re.each do |entry|
325
- instance = c2.new entry
331
+ instance = class2.new entry
326
332
  result.push instance
327
333
  end
328
334
  result
@@ -338,26 +344,26 @@ module Ink
338
344
  # [param params:] Additional SQL syntax like GROUP BY (optional)
339
345
  # [returns:] Array of class2 instances from the SQL result set
340
346
  def find_references(class1, class1_id, class2, params="")
341
- c1 = (class1.is_a? Class) ? class1 : Ink::Model.classname(class1)
342
- c2 = (class2.is_a? Class) ? class2 : Ink::Model.classname(class2)
347
+ class1 = Ink::Model.classname(class1) unless class1.is_a? Class
348
+ class2 = Ink::Model.classname(class2) unless class2.is_a? Class
343
349
  result = Array.new
344
350
  relationship = nil
345
- c1.foreign.each do |k,v|
346
- relationship = v if k.downcase == c2.class_name.downcase
351
+ class1.foreign.each do |k,v|
352
+ relationship = v if k == class2.class_name
347
353
  end
348
354
  return result if relationship == "many_many"
349
355
  re = Array.new
350
- fk1 = c1.foreign_key[0]
351
- tablename1 = c1.table_name
352
- tablename2 = c2.table_name
353
- if ((c1.class_name.downcase <=> c2.class_name.downcase) < 0 and relationship == "one_one") or relationship == "one_many"
354
- 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});"
356
+ fk1 = class1.foreign_key
357
+ tablename1 = class1.table_name
358
+ tablename2 = class2.table_name
359
+ if ((class1.class_name <=> class2.class_name) < 0 and relationship == "one_one") or relationship == "one_many"
360
+ re = self.query "SELECT * FROM #{tablename2} WHERE #{class2.primary_key}=(SELECT #{class2.foreign_key} FROM #{tablename1} WHERE #{class1.primary_key}=#{class1_id});"
355
361
  else
356
362
  re = self.query "SELECT * FROM #{tablename2} WHERE #{fk1} = #{class1_id} #{params};"
357
363
  end
358
364
 
359
365
  re.each do |entry|
360
- instance = c2.new entry
366
+ instance = class2.new entry
361
367
  result.push instance
362
368
  end
363
369
  result
@@ -375,7 +381,7 @@ module Ink
375
381
  def find_reference(class1, class1_id, class2, params="")
376
382
  result_array = self.find_references class1, class1_id, class2, params
377
383
  if result_array.length == 1
378
- result_array[0]
384
+ result_array.first
379
385
  else
380
386
  nil
381
387
  end
@@ -394,21 +400,21 @@ module Ink
394
400
  if type == "one_one"
395
401
  firstclass = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? instance.class : link
396
402
  secondclass = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? link : instance.class
397
- key = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? instance.class.primary_key[0] : instance.class.foreign_key[0]
398
- value = instance.method(instance.class.primary_key[0]).call
399
- @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key[0]}=NULL WHERE #{key}=#{value};"
403
+ key = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? instance.class.primary_key : instance.class.foreign_key
404
+ value = instance.method(instance.class.primary_key).call
405
+ @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key}=NULL WHERE #{key}=#{value};"
400
406
  elsif type == "one_many" or type == "many_one"
401
407
  firstclass = (type == "one_many") ? instance.class : link
402
408
  secondclass = (type == "one_many") ? link : instance.class
403
- key = (type == "one_many") ? instance.class.primary_key[0] : instance.class.foreign_key[0]
404
- value = instance.method(instance.class.primary_key[0]).call
405
- @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key[0]}=NULL WHERE #{key}=#{value};"
409
+ key = (type == "one_many") ? instance.class.primary_key : instance.class.foreign_key
410
+ value = instance.method(instance.class.primary_key).call
411
+ @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key}=NULL WHERE #{key}=#{value};"
406
412
  elsif type == "many_many"
407
413
  tablename1 = instance.class.table_name
408
414
  tablename2 = link.table_name
409
415
  union_class = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? "#{tablename1}_#{tablename2}" : "#{tablename2}_#{tablename1}"
410
- value = instance.method(instance.class.primary_key[0]).call
411
- @db.query "DELETE FROM #{union_class} WHERE #{instance.class.foreign_key[0]}=#{value};"
416
+ value = instance.method(instance.class.primary_key).call
417
+ @db.query "DELETE FROM #{union_class} WHERE #{instance.class.foreign_key}=#{value};"
412
418
  end
413
419
  end
414
420
 
@@ -427,13 +433,13 @@ module Ink
427
433
  if value.is_a? Array
428
434
  value.each do |v|
429
435
  if v.instance_of? link
430
- to_add.push(v.method(link.primary_key[0]).call)
436
+ to_add.push(v.method(link.primary_key).call)
431
437
  else
432
438
  to_add.push v
433
439
  end
434
440
  end
435
441
  elsif value.instance_of? link
436
- to_add.push(value.method(link.primary_key[0]).call)
442
+ to_add.push(value.method(link.primary_key).call)
437
443
  else
438
444
  to_add.push value
439
445
  end
@@ -455,30 +461,30 @@ module Ink
455
461
  def create_link(instance, link, type, fk)
456
462
  if type == "one_one"
457
463
  if (instance.class.name.downcase <=> link.name.downcase) < 0
458
- re = self.find(link.name, "WHERE #{link.primary_key[0]}=#{fk};")[0]
464
+ re = self.find(link.name, "WHERE #{link.primary_key}=#{fk};").first
459
465
  self.delete_all_links re, instance.class, type
460
466
  end
461
467
  firstclass = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? instance.class : link
462
468
  secondclass = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? link : instance.class
463
- key = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? instance.class.primary_key[0] : link.primary_key[0]
464
- value = instance.method(instance.class.primary_key[0]).call
469
+ key = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? instance.class.primary_key : link.primary_key
470
+ value = instance.method(instance.class.primary_key).call
465
471
  fk_set = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? fk : value
466
472
  value_set = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? value : fk
467
- @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key[0]}=#{fk} WHERE #{key}=#{value};"
473
+ @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key}=#{fk} WHERE #{key}=#{value};"
468
474
  elsif type == "one_many" or type == "many_one"
469
475
  firstclass = (type == "one_many") ? instance.class : link
470
476
  secondclass = (type == "one_many") ? link : instance.class
471
- key = (type == "one_many") ? instance.class.primary_key[0] : link.primary_key[0]
472
- value = instance.method(instance.class.primary_key[0]).call
477
+ key = (type == "one_many") ? instance.class.primary_key : link.primary_key
478
+ value = instance.method(instance.class.primary_key).call
473
479
  fk_set = (type == "one_many") ? fk : value
474
480
  value_set = (type == "one_many") ? value : fk
475
- @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key[0]}=#{fk_set} WHERE #{key}=#{value_set};"
481
+ @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key}=#{fk_set} WHERE #{key}=#{value_set};"
476
482
  elsif type == "many_many"
477
483
  tablename1 = instance.class.table_name
478
484
  tablename2 = link.table_name
479
485
  union_class = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? "#{tablename1}_#{tablename2}" : "#{tablename2}_#{tablename1}"
480
- value = instance.method(instance.class.primary_key[0]).call
481
- @db.query "INSERT INTO #{union_class} (#{instance.class.foreign_key[0]}, #{link.foreign_key[0]}) VALUES (#{value}, #{fk});"
486
+ value = instance.method(instance.class.primary_key).call
487
+ @db.query "INSERT INTO #{union_class} (#{instance.class.foreign_key}, #{link.foreign_key}) VALUES (#{value}, #{fk});"
482
488
  end
483
489
  end
484
490
 
@@ -140,8 +140,12 @@ module Ink
140
140
  self.class.fields.each do |k,v|
141
141
  if data.is_a? Array
142
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
143
+ if self.class.primary_key != k or data.length == self.class.fields.length
144
+ init_field k, data[i]
145
+ i += 1
146
+ else
147
+ init_field self.class.primary_key, nil
148
+ end
145
149
  else
146
150
  raise LoadError.new("Model cannot be loaded, argument missing: #{key}") if not data.key?(k.to_s) and self.class.primary_key != k
147
151
  init_field k, data[k.to_s]
@@ -258,28 +262,26 @@ module Ink
258
262
  string = Array.new
259
263
  keystring = Array.new
260
264
  valuestring = Array.new
261
- fields = self.class.fields
262
265
  pkvalue = nil
263
- for i in 0...fields.keys.length
264
- k = fields.keys[i]
266
+ self.class.fields.each do |k,v|
265
267
  value = instance_variable_get "@#{k}"
266
- value = "NULL" if not value
267
- if k != self.class.primary_key[0]
268
+ value = "NULL" if value.nil?
269
+ if k != self.class.primary_key
268
270
  string.push "`#{k}`=#{(value.is_a?(Numeric)) ? value : "\'#{value}\'"}"
269
271
  keystring.push "`#{k}`"
270
272
  valuestring.push "#{(value.is_a?(Numeric)) ? value : "\'#{value}\'"}"
271
273
  else
272
- pkvalue = "WHERE `#{self.class.primary_key[0]}`=#{(value.is_a?(Numeric)) ? value : "\'#{value}\'"}"
274
+ pkvalue = "WHERE `#{self.class.primary_key}`=#{(value.is_a?(Numeric)) ? value : "\'#{value}\'"}"
273
275
  end
274
276
  end
275
277
  if pkvalue
276
278
  response = Ink::Database.database.find self.class, pkvalue
277
- if response.length == 1
278
- Ink::Database.database.query "UPDATE #{self.class.table_name} SET #{string * ","} #{pkvalue};"
279
- elsif response.length == 0
279
+ if response.empty?
280
280
  Ink::Database.database.query "INSERT INTO #{self.class.table_name} (#{keystring * ","}) VALUES (#{valuestring * ","});"
281
281
  pk = Ink::Database.database.last_inserted_pk(self.class)
282
- instance_variable_set "@#{self.class.primary_key[0]}", pk.is_a?(Numeric) ? pk : "\'#{pk}\'" if pk
282
+ instance_variable_set "@#{self.class.primary_key}", pk.is_a?(Numeric) ? pk : "\'#{pk}\'" if pk
283
+ else
284
+ Ink::Database.database.query "UPDATE #{self.class.table_name} SET #{string * ","} #{pkvalue};"
283
285
  end
284
286
  end
285
287
 
@@ -321,7 +323,7 @@ module Ink
321
323
  relationship = self.class.foreign[c.class_name]
322
324
  if relationship
323
325
  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)
324
- instance_variable_set("@#{c.table_name}", (relationship =~ /^one_/) ? result_array[0] : result_array)
326
+ instance_variable_set("@#{c.table_name}", (relationship =~ /^one_/) ? result_array.first : result_array)
325
327
  true
326
328
  else
327
329
  false
@@ -340,26 +342,28 @@ module Ink
340
342
 
341
343
  string = "CREATE TABLE #{self.table_name} ("
342
344
  mfk = self.foreign_key
343
- fields = self.fields
344
- for i in 0...fields.keys.length
345
- k = fields.keys[i]
346
- string += "`#{k}` #{fields[k]*" "}" if k != self.primary_key[0]
347
- string += "#{Ink::Database.database.primary_key_autoincrement(k)*" "}" if k == self.primary_key[0]
348
- string += "," if i < fields.keys.length - 1
349
- end
345
+ string += self.fields.map do |k,v|
346
+ if k != self.primary_key
347
+ "`#{k}` #{v*" "}"
348
+ else
349
+ "#{Ink::Database.database.primary_key_autoincrement(k)*" "}"
350
+ end
351
+ end.join(",")
350
352
 
351
353
  if self.respond_to? :foreign
352
- foreign = self.foreign
353
- for i in 0...foreign.keys.length
354
- k = foreign.keys[i]
355
- v = foreign[k]
356
- fk = Ink::Model::classname(k).foreign_key
357
- string += ",`#{fk[0]}` #{fk[1]}" if fk.length > 0 and (v == "one_many" or (v == "one_one" and (self.name <=> k) < 0))
358
-
359
- if mfk.length > 0 and fk.length > 1 and v == "many_many" and (self.name <=> k) < 0
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]});"
361
- end
362
- end
354
+ tmp = self.foreign.map do |k,v|
355
+ f_class = Ink::Model::classname(k)
356
+ if v == "many_many" and (self.name <=> k) < 0
357
+ result.push "CREATE TABLE #{self.table_name}_#{Ink::Model::str_to_tablename(k)} (#{Ink::Database.database.primary_key_autoincrement*" "}, `#{self.foreign_key}` #{self.foreign_key_type}, `#{f_class.foreign_key}` #{f_class.foreign_key_type});"
358
+ nil
359
+ end
360
+ if v == "one_many" or (v == "one_one" and (self.name <=> k) < 0)
361
+ "`#{f_class.foreign_key}` #{f_class.foreign_key_type}"
362
+ else
363
+ nil
364
+ end
365
+ end.compact.join(",")
366
+ string += ",#{tmp}" if not tmp.empty?
363
367
  end
364
368
  string += ");"
365
369
  result.push string
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: '2.0'
4
+ version: 2.0.1
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-03-23 00:00:00.000000000 Z
12
+ date: 2013-03-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fcgi