webink 2.0 → 2.0.1

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