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 +11 -9
- data/bin/webink_database +4 -2
- data/lib/webink/controller.rb +66 -61
- data/lib/webink/database.rb +57 -51
- data/lib/webink/model.rb +35 -31
- metadata +2 -2
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
|
data/bin/webink_database
CHANGED
@@ -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}:"
|
data/lib/webink/controller.rb
CHANGED
@@ -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
|
32
|
-
#
|
33
|
-
#
|
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
|
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
|
85
|
-
# route configurations must include a variable
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
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
|
93
|
-
# the project path etc. (and is also using
|
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
|
103
|
-
# that is set in the routes.rb. The hash includes the attributes
|
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
|
108
|
-
# from the routes.rb), which you can use to dynamically reroute
|
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.
|
123
|
-
# basic support for it in webink, that will make certain
|
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
|
-
#
|
127
|
-
#
|
128
|
-
#
|
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
|
145
|
-
# by the dispatcher, and include keys like: :get, :post and :config.
|
146
|
-
# matched routes are put there, :controller, :module and any
|
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
|
156
|
-
# project. Subfolders are allowed to be specified. All instance
|
157
|
-
# accessible from within the template, as are any instance
|
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
|
data/lib/webink/database.rb
CHANGED
@@ -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
|
-
|
245
|
-
table_name =
|
246
|
-
pk_name =
|
247
|
-
return if
|
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.
|
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
|
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
|
-
|
289
|
+
class_name = Ink::Model.classname(class_name) unless class_name.is_a? Class
|
286
290
|
result = Array.new
|
287
|
-
table_name =
|
288
|
-
return result if
|
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 =
|
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
|
-
|
310
|
-
|
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
|
-
|
314
|
-
relationship = v if k
|
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 =
|
318
|
-
pk2 =
|
319
|
-
fk2 =
|
320
|
-
tablename1 =
|
321
|
-
tablename2 =
|
322
|
-
union_class = ((
|
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 =
|
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
|
-
|
342
|
-
|
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
|
-
|
346
|
-
relationship = v if k
|
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 =
|
351
|
-
tablename1 =
|
352
|
-
tablename2 =
|
353
|
-
if ((
|
354
|
-
re = self.query "SELECT * FROM #{tablename2} WHERE #{
|
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 =
|
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
|
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
|
398
|
-
value = instance.method(instance.class.primary_key
|
399
|
-
@db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key
|
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
|
404
|
-
value = instance.method(instance.class.primary_key
|
405
|
-
@db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key
|
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
|
411
|
-
@db.query "DELETE FROM #{union_class} WHERE #{instance.class.foreign_key
|
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
|
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
|
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
|
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
|
464
|
-
value = instance.method(instance.class.primary_key
|
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
|
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
|
472
|
-
value = instance.method(instance.class.primary_key
|
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
|
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
|
481
|
-
@db.query "INSERT INTO #{union_class} (#{instance.class.foreign_key
|
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
|
|
data/lib/webink/model.rb
CHANGED
@@ -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
|
-
|
144
|
-
|
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
|
-
|
264
|
-
k = fields.keys[i]
|
266
|
+
self.class.fields.each do |k,v|
|
265
267
|
value = instance_variable_get "@#{k}"
|
266
|
-
value = "NULL" if
|
267
|
-
if k != self.class.primary_key
|
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
|
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.
|
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
|
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
|
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
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
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
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
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:
|
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-
|
12
|
+
date: 2013-03-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fcgi
|