webink 2.1.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,28 +1,26 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'simple_mmap'
4
- require 'webink/beauty'
3
+ require 'webink'
5
4
 
6
5
  config = nil
7
6
  model_classes = Array.new
8
7
 
9
8
  begin
10
- config = Ink::Beauty.load_config "./"
9
+ config = Ink::Beauty.new.load_config
11
10
  rescue Exception => bang
12
11
  puts "Error while loading config: #{bang}."
13
12
  end
14
13
 
15
- require "#{config["db_type"]}"
16
- require 'webink'
14
+ require "#{config[:db_type]}"
17
15
 
18
16
  models = Dir.new "./models"
19
17
  models.each do |model|
20
18
  load "#{models.path}/#{model}" if model =~ /\.rb$/
21
- model_classes.push Ink::Model.classname($1) if model =~ /^(.*)\.rb$/
19
+ model_classes << Ink::Model.classname($1) if model =~ /^(.*)\.rb$/
22
20
  end
23
21
 
24
22
  begin
25
- Ink::Database.create config
23
+ Ink::Database.create(config)
26
24
  db = Ink::Database.database
27
25
  db_tables = db.tables
28
26
 
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ config_ru = <<CFG_RU
4
+ require 'erb'
5
+ require 'webink'
6
+
7
+ run Ink::Beauty.new
8
+ CFG_RU
9
+
10
+ config_rb = <<CFG_RB
11
+ Ink::Beauty.config = {
12
+ #sqlite3 config
13
+ :db_type => "sqlite3",
14
+ :db_server => "./db.sqlite",
15
+
16
+ #mysql config
17
+ #:db_type => "mysql"
18
+ #:db_user => "db_username"
19
+ #:db_pass => "db_password"
20
+ #:db_database => "db_database_name"
21
+ #:db_server => "localhost"
22
+ }
23
+ CFG_RB
24
+
25
+ routes_rb = <<RT_RB
26
+ Ink::Beauty.root = ""
27
+
28
+ Ink::Beauty.routes = [
29
+ [ /^\\/([^\\/]+)\\/([^\\/]+)\\/?$/, {:controller => "$1", :module => "$2"} ],
30
+ [ /^\\/([^\\/]+)\\/?$/, {:controller => "$1", :module => "index"} ],
31
+ [ /^\\/?$/, {:controller => "admin", :module => "index"} ],
32
+ ]
33
+ RT_RB
34
+
35
+ if File.exist?("config") or File.exist?("config.rb")
36
+ puts "Directory already initialized. Exiting."
37
+ exit(0)
38
+ end
39
+
40
+ File.open("config.ru", "w"){ |f| f.puts config_ru }
41
+ File.open("config.rb", "w"){ |f| f.puts config_rb }
42
+ File.open("routes.rb", "w"){ |f| f.puts routes_rb }
43
+ Dir.mkdir("controllers", 0775)
44
+ Dir.mkdir("models", 0775)
45
+ Dir.mkdir("views", 0775)
46
+ Dir.mkdir("files", 0775)
47
+ File.chmod(0775, "config.ru", "config.rb", "routes.rb")
@@ -1,3 +1,4 @@
1
+ require 'webink/beauty'
1
2
  require 'webink/model'
2
3
  require 'webink/controller'
3
4
  require 'webink/database'
@@ -3,78 +3,193 @@ module Ink
3
3
  # = Beauty class
4
4
  #
5
5
  # This class provides a set of tools for loading config and init scripts
6
- # as well as the route-matching. It makes the dispatcher code much more
7
- # beautiful, hence the name.
8
- #
9
- #
6
+ # as well as the route-matching. Formerly it made the dispatcher code
7
+ # much more beautiful, hence the name.
8
+ # Since 3.0.0 it handles the dispatching for rack and serves static files
9
+ # from ./files/*
10
+ #
11
+ #
10
12
  #
11
13
  class Beauty
12
-
13
- # Class method
14
- #
15
- # Attempts to load the init file of the project or raises a LoadError.
16
- # [param script:] Project folder path
17
- # [returns:] valid init file path
18
- def self.load_init(script)
19
- script = "#{File.dirname(script)}/init"
20
- script = "#{script}.rb" if not File.exist? script
21
- raise LoadError.new("Init not found.") if not File.exist? script
22
- script
14
+
15
+ # Class accessor definitions
16
+ #
17
+ class << self
18
+ attr_accessor :routes, :config, :root
19
+ end
20
+
21
+ # Constructor
22
+ #
23
+ def initialize
24
+ @params = {}
25
+ end
26
+
27
+ # Instance method
28
+ #
29
+ # Rackup call
30
+ # Initializes the webink environment
31
+ # Rescues all kinds of errors and responds with error codes
32
+ # [param env:] rack environment
33
+ # [returns:] Rack-compatible array
34
+ def call(env)
35
+ @params = {} #reset
36
+ @env = env
37
+ controller = self.init
38
+ if controller and not @params[:file]
39
+ Ink::Database.create(@params[:config])
40
+ response = controller.verify(@params[:module]).call
41
+ Ink::Database.database.close
42
+ response || [404, {}, self.error_mapping(404)]
43
+ elsif File.exist?("."+@params[:file])
44
+ [ 200, {}, File.open("."+@params[:file], File::RDONLY) ]
45
+ else
46
+ [ 404, {}, self.error_mapping(404) ]
47
+ end
48
+ rescue LoadError => bang
49
+ render_error(404, "LoadError", bang)
50
+ rescue NotImplementedError => bang
51
+ render_error(500, "NotImplementedError", bang)
52
+ rescue ArgumentError => bang
53
+ render_error(500, "ArgumentError", bang)
54
+ rescue RuntimeError => bang
55
+ render_error(500, "RuntimeError", bang)
56
+ rescue NameError => bang
57
+ render_error(500, "NameError", bang)
58
+ rescue Exception, Error => bang
59
+ render_error(500, "Exception", bang)
60
+ end
61
+
62
+ # Instance method
63
+ #
64
+ # Loads models and the controller. Requires the database type.
65
+ # [returns:] Controller class
66
+ def load_env
67
+ require "#{@params[:config][:db_type]}"
68
+ Dir.new("./models").each{ |m| load "./models/#{m}" if m =~ /\.rb$/ }
69
+ load "./controllers/#{@params[:controller]}.rb"
70
+ Ink::Controller.verify(@params[:controller]).new(@params)
71
+ end
72
+
73
+ # Instance method
74
+ #
75
+ # Generates a param hash including the config, route and get/post
76
+ # parameters.
77
+ # [returns:] Controller class
78
+ def init
79
+ req = Rack::Request.new(@env)
80
+ @params.merge!({:header => {}, :cookie => req.cookies})
81
+ @params[:get] = Rack::Utils.parse_query(@env["QUERY_STRING"], '&;') || {}
82
+ @params[:post] = {}
83
+ if @env['rack.input'].is_a?(StringIO)
84
+ @params[:post] =
85
+ Rack::Utils.parse_query(@env['rack.input'].read, "&;\n")
86
+ end
87
+ self.load_config
88
+ self.load_routes
89
+ @params[:file] ? nil : self.load_env #static file requests are nil
23
90
  end
24
-
25
- # Class method
26
- #
91
+
92
+ # Instance method
93
+ #
27
94
  # Attempts to load the config file of the project or raises a LoadError.
28
- # Once loaded, the config is evaluated and can raise a RuntimeError, or
29
- # it is returned
30
- # [param script:] Project folder path
95
+ # Once loaded, the config is returned
31
96
  # [returns:] a valid config
32
- def self.load_config(script)
33
- config = "#{File.dirname(script)}/config"
34
- config = "#{config}.rb" if not File.exist? config
35
- raise LoadError.new("Config not found.") if not File.exist? config
36
- fhandle = SimpleMmap::MappedFile.new(config)
37
- config = eval fhandle.read_window_data(0,fhandle.size)
38
- fhandle.close
39
- raise RuntimeError.new("Config error.") if not config.instance_of? Hash
40
- config
97
+ def load_config
98
+ config = "./config"
99
+ config = "#{config}.rb" unless File.exist?(config)
100
+ raise LoadError.new("Config not found.") unless File.exist?(config)
101
+ load config
102
+ if Beauty.config.nil?
103
+ raise LoadError.new("Config extension error on Beauty")
104
+ end
105
+ @params[:config] = Beauty.config
106
+ Beauty.config
41
107
  end
42
-
43
- # Class method
44
- #
45
- # Attempts to load the routes file of the project or raises a LoadError
46
- # [param script:] Project folder path
47
- # [returns:] valid routes file path
48
- def self.load_routes(script)
49
- routes = "#{File.dirname(script)}/routes"
50
- routes = "#{routes}.rb" if not File.exist? routes
51
- raise LoadError.new("Routes not found.") if not File.exist? routes
52
- routes
108
+
109
+ # Instance method
110
+ #
111
+ # Attempts to load the routes file of the project or raises a LoadError.
112
+ # Determines and stores the current route in the @params
113
+ def load_routes
114
+ routes = "./routes"
115
+ routes = "#{routes}.rb" unless File.exist?(routes)
116
+ raise LoadError.new("Routes not found.") unless File.exist?(routes)
117
+ load routes
118
+ if Beauty.routes.nil?
119
+ raise LoadError.new("Route extension error on Beauty")
120
+ elsif Beauty.root.nil?
121
+ raise LoadError.new("Root extension error on Beuaty")
122
+ end
123
+ @params.merge!(self.routing(@env["REQUEST_PATH"])) if @env["REQUEST_PATH"]
53
124
  end
54
-
55
- # Class method
56
- #
125
+
126
+ # Instance method
127
+ #
57
128
  # Attempts to match the params onto the routes and return the results in
58
129
  # form of a Hash.
59
- # [param root:] Relative project folder path to the server document path
60
- # [param routes:] Array of Arrays: regex, Hash(Symbol => String)
61
- # [param params:] Requested string
130
+ # Possible root route is extracted and routes matching to /files/* will
131
+ # be stored in the match.
132
+ # [param str:] Requested string
62
133
  # [returns:] Hash of Symbol => String
63
- def self.routing(root, routes, params)
134
+ def routing(str)
135
+ root = Beauty.root
136
+ root = $1 if root =~ /(.*)\/$/
64
137
  match = { :root => root }
65
- routes.each do |entry|
138
+ if str =~ /^#{root}(.*)\/?$/
139
+ str = $1
140
+ else
141
+ raise LoadError.new("No matching route found")
142
+ end
143
+ # match file route:
144
+ if str =~ /^(\/files\/.+)$/
145
+ return match.merge({ :file => $1 })
146
+ end
147
+ Beauty.routes.each do |entry|
66
148
  k = entry[0]
67
149
  v = entry[1]
68
- if params =~ k
150
+ if str =~ k
69
151
  v.each do |sys,e|
70
- match[sys] = (e =~ /^\$\d+$/ and params =~ k and eval e) ? (eval e) : e
152
+ match[sys] =
153
+ (e =~ /^\$\d+$/ and str =~ k and eval e) ? (eval e) : e
71
154
  end
72
155
  break
73
156
  end
74
157
  end
158
+ raise LoadError.new("No matching route found") if match.keys.length <= 1
75
159
  match
76
160
  end
77
-
161
+
162
+ # Instance method
163
+ #
164
+ # Renders error stacktraces or errors back to the
165
+ # user
166
+ # [param code:] Error code integer
167
+ # [param type:] Exception type string
168
+ # [param bang:] Exception instance
169
+ # [returns:] Rack-compatible array
170
+ def render_error(code, type, bang)
171
+ if Beauty.config and Beauty.config[:production]
172
+ [code, {}, self.error_mapping(code)]
173
+ else
174
+ [200, {}, [
175
+ "<b>#{type}</b>",
176
+ "<em><pre>#{bang}</pre></em>",
177
+ "<pre>#{bang.backtrace.join("\n")}</pre>"
178
+ ]]
179
+ end
180
+ end
181
+
182
+ # Instance method
183
+ #
184
+ # Maps error code integers to error strings
185
+ # [param code:] Error code integer
186
+ # [returns:] Error string
187
+ def error_mapping(code)
188
+ {
189
+ 404 => "404 Page not found",
190
+ 500 => "500 Internal error",
191
+ }[code]
192
+ end
193
+
78
194
  end
79
-
80
195
  end
@@ -12,7 +12,8 @@ module Ink
12
12
  # class App < Ink::Controller
13
13
  #
14
14
  # def index
15
- # redirect_to :controller => "my_app", :module => "feed", :id => 29382374
15
+ # redirect_to :controller => "my_app", :module => "feed",
16
+ # :id => 29382374
16
17
  # end
17
18
  #
18
19
  # def feed
@@ -29,9 +30,11 @@ module Ink
29
30
  # end
30
31
  #
31
32
  # A controller named App should have the filename app.rb and be
32
- # placed inside the project controller folder. It can have
33
+ # placed inside the project controllers folder. It can have
33
34
  # instance methods that are usually refered to as modules.
34
35
  # So a route should contain at least a :controller and a :module.
36
+ # Note that controller filenames are not camelized when they are
37
+ # being searched for by the dispatcher.
35
38
  #
36
39
  # In the sample above there are three modules, index redirects
37
40
  # to feed, feed renders a template and partial renders a partial.
@@ -72,10 +75,11 @@ module Ink
72
75
  # The routes being evaluated by the dispatcher are simple regular expressions.
73
76
  # This example fits the controller from earlier.
74
77
  #
75
- # root = "/folder"
78
+ # Beauty.root = "/folder"
76
79
  #
77
- # routes = [
78
- # [ /^\/([^\/]+)\/([^\/]+)(\/([0-9]+))?$/, {:controller => "$1", :module => "$2", :id => "$4"} ],
80
+ # Beauty.routes = [
81
+ # [ /^\/([^\/]+)\/([^\/]+)(\/([0-9]+))?$/,
82
+ # {:controller => "$1", :module => "$2", :id => "$4"} ],
79
83
  # [ /^\/([^\/]+)\/?$/, {:controller => "$1", :module => "index"} ],
80
84
  # [ /^\/?$/, {:controller => "app", :module => "index"} ],
81
85
  # ]
@@ -94,7 +98,8 @@ module Ink
94
98
  # will dynamically match the project path etc. (and is also using
95
99
  # the root variable from the routes.rb)
96
100
  #
97
- # link_to "name", "controller", "module", "param1", "param2", {:class => "h1", :id => "14"}
101
+ # link_to "name", "controller", "module", "param1", "param2",
102
+ # {:class => "h1", :id => "14"}
98
103
  #
99
104
  # The link above will produce this:
100
105
  #
@@ -126,18 +131,18 @@ module Ink
126
131
  # There is some basic support for it in webink, that will make certain
127
132
  # bits easier. For more information have a look at the blog-demo.
128
133
  #
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.
134
+ # Each controller usually expects cookies to work. Whenever cookies
135
+ # do not work, or you do not intend to use them in the first place,
136
+ # path_to and link_to watch out for the instance variables @session_key
137
+ # and @session_id which are added via GET to the path/hyperlink, that
138
+ # they construct. Therefore the tools should not be used for external
139
+ # linking. The dispatcher automatically filters the GET session_id when
140
+ # using POST and adds it to the cgi.params, so sessions can be used
141
+ # confortably.
137
142
  #
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.
143
+ # Per default, the @session_key should be "_session_id", but the
144
+ # controller offers some freedom, in case you may want a different
145
+ # key name for some reason.
141
146
  #
142
147
  #
143
148
  #
@@ -169,17 +174,18 @@ module Ink
169
174
  template = File.open "./views/#{args[:template]}.html.erb", "r"
170
175
  erb = ERB.new template.readlines * "\n"
171
176
  template.close
172
- puts @params[:cgi].header
173
- erb.run self.getBinding(args[:locals])
177
+ [200, @params[:header], erb.result(self.getBinding(args[:locals]))]
174
178
  elsif args[:partial]
175
- template = File.open "./views/#{(File.dirname(args[:partial]) != ".") ? "#{File.dirname(args[:partial])}/" : ""}_#{File.basename(args[:partial])}.html.erb", "r"
179
+ template = File.open "./views/#{
180
+ (File.dirname(args[:partial]) != ".") ?
181
+ "#{File.dirname(args[:partial])}/" : ""
182
+ }_#{File.basename(args[:partial])}.html.erb", "r"
176
183
  erb = ERB.new template.readlines * "\n"
177
184
  template.close
178
185
  if not args[:standalone]
179
- erb.result self.getBinding(args[:locals])
186
+ erb.result(self.getBinding(args[:locals]))
180
187
  else
181
- puts @params[:cgi].header
182
- erb.run self.getBinding(args[:locals])
188
+ [200, @params[:header], erb.result(self.getBinding(args[:locals]))]
183
189
  end
184
190
  else
185
191
  nil
@@ -201,8 +207,8 @@ module Ink
201
207
  p[k] = v
202
208
  end
203
209
  if p[:controller] and p[:module]
204
- controller = (Ink::Controller.verify p[:controller]).new p
205
- (controller.verify p[:module]).call
210
+ controller = Ink::Controller.verify(p[:controller]).new(p)
211
+ controller.verify(p[:module]).call
206
212
  else
207
213
  nil
208
214
  end
@@ -218,8 +224,10 @@ module Ink
218
224
  # [param args:] Array of Strings and Hashes
219
225
  # [returns:] Hyperlink
220
226
  def link_to(*args)
221
- raise ArgumentError.new("Expects an array.") if not args.instance_of? Array and args.length < 2
222
- href = (@params[:root].length == 0) ? "/" : "#{@params[:root]}#{(@params[:root][@params[:root].length-1].chr == "/") ? "" : "/"}"
227
+ if not args.instance_of? Array and args.length < 2
228
+ raise ArgumentError.new("Expects an array.")
229
+ end
230
+ href = "#{@params[:root]}/"
223
231
  a = "<a "
224
232
  name = args[0]
225
233
  for i in 1...args.length
@@ -245,7 +253,7 @@ module Ink
245
253
  # [param args:] Array of Strings or String
246
254
  # [returns:] path
247
255
  def path_to(*args)
248
- href = (@params[:root].length == 0) ? "/" : "#{@params[:root]}#{(@params[:root][@params[:root].length-1].chr == "/") ? "" : "/"}"
256
+ href = "#{@params[:root]}/"
249
257
 
250
258
  if args.is_a? Array
251
259
  for i in 0...args.length
@@ -275,14 +283,15 @@ module Ink
275
283
  # [param controller:] Controller name string
276
284
  # [returns:] class or nil
277
285
  def self.verify(controller)
278
- if not Module.const_defined? controller.capitalize
279
- if File.exists? "./controllers/#{controller}.rb"
286
+ if not Module.const_defined?(controller.capitalize)
287
+ if File.exists? "./controllers/#{controller}.rb" and
288
+ Module.const_get(controller.capitalize).is_a?(Class)
280
289
  load "./controllers/#{controller}.rb"
281
290
  else
282
291
  raise NameError.new("Controller not found.")
283
292
  end
284
293
  end
285
- ((Module.const_get controller.capitalize).is_a? Class) ? (Module.const_get controller.capitalize) : (raise NameError.new("Controller not found."))
294
+ Module.const_get(controller.capitalize)
286
295
  end
287
296
 
288
297
  # Instance method
@@ -10,21 +10,19 @@ module Ink
10
10
  #
11
11
  # Sample config for MySQL:
12
12
  # config = {
13
- # "escape_post_data" => false,
14
- # "production" => true,
15
- # "db_type" => "mysql",
16
- # "db_user" => "yourusername",
17
- # "db_pass" => "yourpassword",
18
- # "db_database" => "yourdatabase",
19
- # "db_server" => "localhost",
13
+ # :production => true,
14
+ # :db_type => "mysql",
15
+ # :db_user => "yourusername",
16
+ # :db_pass => "yourpassword",
17
+ # :db_database => "yourdatabase",
18
+ # :db_server => "localhost",
20
19
  # }
21
20
  #
22
21
  # Sample config for SQLite3:
23
22
  # config = {
24
- # "escape_post_data" => false,
25
- # "production" => true,
26
- # "db_type" => "sqlite3",
27
- # "db_server" => "/full/path/to/database.sqlite",
23
+ # :production => true,
24
+ # :db_type => "sqlite3",
25
+ # :db_server => "/full/path/to/database.sqlite",
28
26
  # }
29
27
  #
30
28
  # == Usage
@@ -109,12 +107,13 @@ module Ink
109
107
  # possible.
110
108
  # [param config:] Hash of config parameters
111
109
  def initialize(config)
112
- @type = config["db_type"]
110
+ @type = config[:db_type]
113
111
  if @type == "mysql"
114
- @db = Mysql.real_connect(config["db_server"],config["db_user"],config["db_pass"],config["db_database"])
112
+ @db = Mysql.real_connect(config[:db_server],config[:db_user],
113
+ config[:db_pass],config[:db_database])
115
114
  @db.reconnect = true
116
115
  elsif @type == "sqlite3"
117
- @db = SQLite3::Database.new(config["db_server"])
116
+ @db = SQLite3::Database.new(config[:db_server])
118
117
  else
119
118
  raise ArgumentError.new("Database undefined.")
120
119
  end
@@ -140,7 +139,11 @@ module Ink
140
139
  # Returns the Database instance or raises a Runtime Error
141
140
  # [returns:] Database instance
142
141
  def self.database
143
- (@@database) ? @@database : (raise RuntimeError.new("No Database found. Create one first"))
142
+ if @@database
143
+ @@database
144
+ else
145
+ raise RuntimeError.new("No Database found. Create one first")
146
+ end
144
147
  end
145
148
 
146
149
  # Instance method
@@ -158,7 +161,9 @@ module Ink
158
161
  end
159
162
  end
160
163
  elsif @type == "sqlite3"
161
- re = @db.query "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;"
164
+ re = @db.query <<QUERY
165
+ SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;
166
+ QUERY
162
167
  re.each do |row|
163
168
  row.each do |t|
164
169
  result.push t
@@ -273,7 +278,9 @@ module Ink
273
278
  # [param class_name:] Defines the __table__ name or class
274
279
  # [returns:] primary key or nil
275
280
  def last_inserted_pk(class_name)
276
- class_name = Ink::Model.classname(class_name) unless class_name.is_a? Class
281
+ unless class_name.is_a?(Class)
282
+ class_name = Ink::Model.classname(class_name)
283
+ end
277
284
  table_name = class_name.table_name
278
285
  pk_name = class_name.primary_key
279
286
  return if table_name.nil? or pk_name.nil?
@@ -302,7 +309,8 @@ module Ink
302
309
  # [param class_name:] Defines the class name or class
303
310
  # [param params:] Additional SQL syntax like WHERE conditions (optional)
304
311
  def remove(class_name, params="")
305
- table_name = (class_name.is_a? Class) ? class_name.table_name : Ink::Model.str_to_tablename(class_name)
312
+ table_name = (class_name.is_a? Class) ? class_name.table_name :
313
+ Ink::Model.str_to_tablename(class_name)
306
314
  return if table_name.nil?
307
315
  self.query("DELETE FROM #{table_name} #{params};")
308
316
  end
@@ -310,11 +318,14 @@ module Ink
310
318
  # Instance method
311
319
  #
312
320
  # Retrieve class instances, that are loaded with the database result set.
313
- # [param class_name:] Defines the class name or class which should be queried
321
+ # [param class_name:] Defines the class name or class which should be
322
+ # queried
314
323
  # [param params:] Additional SQL syntax like WHERE conditions (optional)
315
324
  # [returns:] Array of class_name instances from the SQL result set
316
325
  def find(class_name, params="")
317
- class_name = Ink::Model.classname(class_name) unless class_name.is_a? Class
326
+ unless class_name.is_a?(Class)
327
+ class_name = Ink::Model.classname(class_name)
328
+ end
318
329
  result = Array.new
319
330
  table_name = class_name.table_name
320
331
  return result if table_name.nil?
@@ -354,7 +365,11 @@ module Ink
354
365
  union_class = ((class1.class_name <=> class2.class_name) < 0) ?
355
366
  "#{tablename1}_#{tablename2}" :
356
367
  "#{tablename2}_#{tablename1}"
357
- re = self.query("SELECT #{tablename2}.* FROM #{union_class}, #{tablename2} WHERE #{union_class}.#{fk1} = #{class1_id} AND #{union_class}.#{fk2} = #{tablename2}.#{pk2} #{params};")
368
+ re = self.query <<QUERY
369
+ SELECT #{tablename2}.* FROM #{union_class}, #{tablename2}
370
+ WHERE #{union_class}.#{fk1} = #{class1_id}
371
+ AND #{union_class}.#{fk2} = #{tablename2}.#{pk2} #{params};
372
+ QUERY
358
373
  re.each do |entry|
359
374
  instance = class2.new entry
360
375
  result.push instance
@@ -384,10 +399,19 @@ module Ink
384
399
  fk1 = class1.foreign_key
385
400
  tablename1 = class1.table_name
386
401
  tablename2 = class2.table_name
387
- if ((class1.class_name <=> class2.class_name) < 0 and relationship == "one_one") or relationship == "one_many"
388
- re = self.query "SELECT * FROM #{tablename2} WHERE #{class2.primary_key}=(SELECT #{class2.foreign_key} FROM #{tablename1} WHERE #{class1.primary_key}=#{class1_id});"
402
+ if ((class1.class_name <=> class2.class_name) < 0 and
403
+ relationship == "one_one") or relationship == "one_many"
404
+ re = self.query <<QUERY
405
+ SELECT * FROM #{tablename2}
406
+ WHERE #{class2.primary_key}=(
407
+ SELECT #{class2.foreign_key} FROM #{tablename1}
408
+ WHERE #{class1.primary_key}=#{class1_id}
409
+ );
410
+ QUERY
389
411
  else
390
- re = self.query "SELECT * FROM #{tablename2} WHERE #{fk1} = #{class1_id} #{params};"
412
+ re = self.query <<QUERY
413
+ SELECT * FROM #{tablename2} WHERE #{fk1} = #{class1_id} #{params};
414
+ QUERY
391
415
  end
392
416
 
393
417
  re.each do |entry|
@@ -400,7 +424,8 @@ module Ink
400
424
  # Instance method
401
425
  #
402
426
  # Retrieve one class2 instance, that is related to the class1 instance with
403
- # primary key class1_id. Only relevant for one_one and one_many relationships
427
+ # primary key class1_id. Only relevant for one_one and one_many
428
+ # relationships
404
429
  # [param class1:] Reference classname or class
405
430
  # [param class1_id:] Primary key value of the reference classname
406
431
  # [param class2:] Match classname or class
@@ -426,23 +451,42 @@ module Ink
426
451
  # [param type:] relationship type
427
452
  def delete_all_links(instance, link, type)
428
453
  if type == "one_one"
429
- firstclass = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? instance.class : link
430
- secondclass = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? link : instance.class
431
- key = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? instance.class.primary_key : instance.class.foreign_key
454
+ firstclass =
455
+ ((instance.class.name.downcase <=> link.name.downcase) < 0) ?
456
+ instance.class : link
457
+ secondclass =
458
+ ((instance.class.name.downcase <=> link.name.downcase) < 0) ?
459
+ link : instance.class
460
+ key =
461
+ ((instance.class.name.downcase <=> link.name.downcase) < 0) ?
462
+ instance.class.primary_key : instance.class.foreign_key
432
463
  value = instance.method(instance.class.primary_key).call
433
- @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key}=NULL WHERE #{key}=#{value};"
464
+ @db.query <<QUERY
465
+ UPDATE #{firstclass.table_name}
466
+ SET #{secondclass.foreign_key}=NULL
467
+ WHERE #{key}=#{value};
468
+ QUERY
434
469
  elsif type == "one_many" or type == "many_one"
435
470
  firstclass = (type == "one_many") ? instance.class : link
436
471
  secondclass = (type == "one_many") ? link : instance.class
437
- key = (type == "one_many") ? instance.class.primary_key : instance.class.foreign_key
472
+ key = (type == "one_many") ? instance.class.primary_key :
473
+ instance.class.foreign_key
438
474
  value = instance.method(instance.class.primary_key).call
439
- @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key}=NULL WHERE #{key}=#{value};"
475
+ @db.query <<QUERY
476
+ UPDATE #{firstclass.table_name}
477
+ SET #{secondclass.foreign_key}=NULL
478
+ WHERE #{key}=#{value};
479
+ QUERY
440
480
  elsif type == "many_many"
441
481
  tablename1 = instance.class.table_name
442
482
  tablename2 = link.table_name
443
- union_class = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? "#{tablename1}_#{tablename2}" : "#{tablename2}_#{tablename1}"
483
+ union_class =
484
+ ((instance.class.name.downcase <=> link.name.downcase) < 0) ?
485
+ "#{tablename1}_#{tablename2}" : "#{tablename2}_#{tablename1}"
444
486
  value = instance.method(instance.class.primary_key).call
445
- @db.query "DELETE FROM #{union_class} WHERE #{instance.class.foreign_key}=#{value};"
487
+ @db.query <<QUERY
488
+ DELETE FROM #{union_class} WHERE #{instance.class.foreign_key}=#{value};
489
+ QUERY
446
490
  end
447
491
  end
448
492
 
@@ -452,10 +496,12 @@ module Ink
452
496
  # link is the class of the related data, and type refers to the
453
497
  # relationship type of the two. When one tries to insert an array
454
498
  # for a x_one relationship, the last entry will be set.
455
- # [param instance:] Instance of a class that refers to an existing database entry
499
+ # [param instance:] Instance of a class that refers to an existing
500
+ # database entry
456
501
  # [param link:] the related class (not a String, but class reference)
457
502
  # [param type:] relationship type
458
- # [param value:] relationship data that was set, either a primary key value, or an instance, or an array of both
503
+ # [param value:] relationship data that was set, either a primary key value,
504
+ # or an instance, or an array of both
459
505
  def create_all_links(instance, link, type, value)
460
506
  to_add = Array.new
461
507
  if value.is_a? Array
@@ -482,7 +528,8 @@ module Ink
482
528
  # The relationship between the two is defined by type. one_one
483
529
  # relationships are placing an additional call to delete_all_links
484
530
  # that will remove conflicts.
485
- # [param instance:] Instance of a class that refers to an existing database entry
531
+ # [param instance:] Instance of a class that refers to an existing database
532
+ # entry
486
533
  # [param link:] the related class (not a String, but class reference)
487
534
  # [param type:] relationship type
488
535
  # [param value:] primary key of the relationship, that is to be created
@@ -492,27 +539,49 @@ module Ink
492
539
  re = self.find(link.name, "WHERE #{link.primary_key}=#{fk};").first
493
540
  self.delete_all_links re, instance.class, type
494
541
  end
495
- firstclass = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? instance.class : link
496
- secondclass = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? link : instance.class
497
- key = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? instance.class.primary_key : link.primary_key
542
+ firstclass =
543
+ ((instance.class.name.downcase <=> link.name.downcase) < 0) ?
544
+ instance.class : link
545
+ secondclass =
546
+ ((instance.class.name.downcase <=> link.name.downcase) < 0) ?
547
+ link : instance.class
548
+ key =
549
+ ((instance.class.name.downcase <=> link.name.downcase) < 0) ?
550
+ instance.class.primary_key : link.primary_key
498
551
  value = instance.method(instance.class.primary_key).call
499
- fk_set = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? fk : value
500
- value_set = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? value : fk
501
- @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key}=#{fk} WHERE #{key}=#{value};"
552
+ fk_set =
553
+ ((instance.class.name.downcase <=> link.name.downcase) < 0) ?
554
+ fk : value
555
+ value_set =
556
+ ((instance.class.name.downcase <=> link.name.downcase) < 0) ?
557
+ value : fk
558
+ @db.query <<QUERY
559
+ UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key}=#{fk}
560
+ WHERE #{key}=#{value};
561
+ QUERY
502
562
  elsif type == "one_many" or type == "many_one"
503
563
  firstclass = (type == "one_many") ? instance.class : link
504
564
  secondclass = (type == "one_many") ? link : instance.class
505
- key = (type == "one_many") ? instance.class.primary_key : link.primary_key
565
+ key = (type == "one_many") ? instance.class.primary_key :
566
+ link.primary_key
506
567
  value = instance.method(instance.class.primary_key).call
507
568
  fk_set = (type == "one_many") ? fk : value
508
569
  value_set = (type == "one_many") ? value : fk
509
- @db.query "UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key}=#{fk_set} WHERE #{key}=#{value_set};"
570
+ @db.query <<QUERY
571
+ UPDATE #{firstclass.table_name} SET #{secondclass.foreign_key}=#{fk_set}
572
+ WHERE #{key}=#{value_set};
573
+ QUERY
510
574
  elsif type == "many_many"
511
575
  tablename1 = instance.class.table_name
512
576
  tablename2 = link.table_name
513
- union_class = ((instance.class.name.downcase <=> link.name.downcase) < 0) ? "#{tablename1}_#{tablename2}" : "#{tablename2}_#{tablename1}"
577
+ union_class =
578
+ ((instance.class.name.downcase <=> link.name.downcase) < 0) ?
579
+ "#{tablename1}_#{tablename2}" : "#{tablename2}_#{tablename1}"
514
580
  value = instance.method(instance.class.primary_key).call
515
- @db.query "INSERT INTO #{union_class} (#{instance.class.foreign_key}, #{link.foreign_key}) VALUES (#{value}, #{fk});"
581
+ @db.query <<QUERY
582
+ INSERT INTO #{union_class}
583
+ (#{instance.class.foreign_key}, #{link.foreign_key}) VALUES (#{value}, #{fk});
584
+ QUERY
516
585
  end
517
586
  end
518
587
 
@@ -139,15 +139,26 @@ module Ink
139
139
  i = 0
140
140
  self.class.fields.each do |k,v|
141
141
  if data.is_a? Array
142
- raise LoadError.new("Model cannot be loaded, wrong number or arguments #{data.length} expected #{self.class.fields.length} or #{self.class.fields.length - 1}") if data.length < self.class.fields.length - 1 or data.length > self.class.fields.length
143
- if self.class.primary_key != k or data.length == self.class.fields.length
142
+ if data.length < self.class.fields.length - 1 or
143
+ data.length > self.class.fields.length
144
+ raise LoadError.new(<<ERR)
145
+ Model cannot be loaded, wrong number or arguments #{data.length} expected
146
+ #{self.class.fields.length} or #{self.class.fields.length - 1}
147
+ ERR
148
+ end
149
+ if self.class.primary_key != k or
150
+ data.length == self.class.fields.length
144
151
  init_field k, data[i]
145
152
  i += 1
146
153
  else
147
154
  init_field self.class.primary_key, nil
148
155
  end
149
156
  else
150
- raise LoadError.new("Model cannot be loaded, argument missing: #{key}") if not data.key?(k.to_s) and self.class.primary_key != k
157
+ if not data.key?(k.to_s) and self.class.primary_key != k
158
+ raise LoadError.new(<<ERR)
159
+ Model cannot be loaded, argument missing: #{key}
160
+ ERR
161
+ end
151
162
  init_field k, data[k.to_s]
152
163
  end
153
164
  end
@@ -188,7 +199,11 @@ module Ink
188
199
  # [key:] String
189
200
  # [value:] Object
190
201
  def init_field(key, value)
191
- raise NameError.new("Model cannot use #{key} as field, it is blocked by primary key") if key.to_s.downcase == "pk"
202
+ if key.to_s.downcase == "pk"
203
+ raise NameError.new(<<ERR)
204
+ Model cannot use #{key} as field, it is blocked by primary key
205
+ ERR
206
+ end
192
207
  entry = self.class.make_safe(value)
193
208
  instance_variable_set("@#{key}", entry)
194
209
 
@@ -231,7 +246,11 @@ module Ink
231
246
  # [key:] String
232
247
  def init_foreign(key)
233
248
  k_table = self.class.str_to_tablename(key)
234
- raise NameError.new("Model cannot use #{k_table} as foreign, it already exists") if k_table == "pk"
249
+ if k_table == "pk"
250
+ raise NameError.new(<<ERR)
251
+ Model cannot use #{k_table} as foreign, it already exists
252
+ ERR
253
+ end
235
254
  if not self.respond_to?(k_table)
236
255
  instance_variable_set("@#{k_table}", nil)
237
256
  self.class.send(:define_method, k_table) do
@@ -250,7 +269,11 @@ module Ink
250
269
  # nil if you do not want to change them. Old references are
251
270
  # automatically removed.
252
271
  def save
253
- raise NotImplementedError.new("Cannot save to Database without field definitions") if not self.class.respond_to? :fields
272
+ if not self.class.respond_to?(:fields)
273
+ raise NotImplementedError.new(<<ERR)
274
+ Cannot save to Database without field definitions
275
+ ERR
276
+ end
254
277
  string = Array.new
255
278
  keystring = Array.new
256
279
  valuestring = Array.new
@@ -259,21 +282,33 @@ module Ink
259
282
  value = instance_variable_get "@#{k}"
260
283
  value = "NULL" if value.nil?
261
284
  if k != self.class.primary_key
262
- string.push "`#{k}`=#{(value.is_a?(Numeric)) ? value : "\'#{value}\'"}"
285
+ string.push "`#{k}`=#{(value.is_a?(Numeric)) ? value :
286
+ "\'#{value}\'"}"
263
287
  keystring.push "`#{k}`"
264
288
  valuestring.push "#{(value.is_a?(Numeric)) ? value : "\'#{value}\'"}"
265
289
  else
266
- pkvalue = "WHERE `#{self.class.primary_key}`=#{(value.is_a?(Numeric)) ? value : "\'#{value}\'"}"
290
+ pkvalue = "WHERE `#{self.class.primary_key}`=#{
291
+ (value.is_a?(Numeric)) ? value : "\'#{value}\'"
292
+ }"
267
293
  end
268
294
  end
269
295
  if pkvalue
270
296
  response = Ink::Database.database.find self.class, pkvalue
271
297
  if response.empty?
272
- Ink::Database.database.query "INSERT INTO #{self.class.table_name} (#{keystring * ","}) VALUES (#{valuestring * ","});"
298
+ Ink::Database.database.query <<QUERY
299
+ INSERT INTO #{self.class.table_name}
300
+ (#{keystring * ","}) VALUES
301
+ (#{valuestring * ","});
302
+ QUERY
273
303
  pk = Ink::Database.database.last_inserted_pk(self.class)
274
- instance_variable_set "@#{self.class.primary_key}", pk.is_a?(Numeric) ? pk : "\'#{pk}\'" if pk
304
+ if pk
305
+ instance_variable_set("@#{self.class.primary_key}",
306
+ pk.is_a?(Numeric) ? pk : "\'#{pk}\'")
307
+ end
275
308
  else
276
- Ink::Database.database.query "UPDATE #{self.class.table_name} SET #{string * ","} #{pkvalue};"
309
+ Ink::Database.database.query <<QUERY
310
+ UPDATE #{self.class.table_name} SET #{string * ","} #{pkvalue};
311
+ QUERY
277
312
  end
278
313
  end
279
314
 
@@ -281,8 +316,10 @@ module Ink
281
316
  self.class.foreign.each do |k,v|
282
317
  value = instance_variable_get "@#{self.class.str_to_tablename(k)}"
283
318
  if value
284
- Ink::Database.database.delete_all_links self, Ink::Model.classname(k), v
285
- Ink::Database.database.create_all_links self, Ink::Model.classname(k), v, value
319
+ Ink::Database.database.delete_all_links(self,
320
+ Ink::Model.classname(k), v)
321
+ Ink::Database.database.create_all_links(self,
322
+ Ink::Model.classname(k), v, value)
286
323
  end
287
324
  end
288
325
  end
@@ -294,15 +331,24 @@ module Ink
294
331
  # obsolete. Disregard from using the instance anymore.
295
332
  # All links between models will be removed also.
296
333
  def delete
297
- raise NotImplementedError.new("Cannot delete from Database without field definitions") if not self.class.respond_to? :fields
334
+ if not self.class.respond_to? :fields
335
+ raise NotImplementedError.new(<<ERR)
336
+ Cannot delete from Database without field definitions
337
+ ERR
338
+ end
298
339
  if self.class.respond_to? :foreign
299
340
  self.class.foreign.each do |k,v|
300
- Ink::Database.database.delete_all_links self, Ink::Model.classname(k), v
341
+ Ink::Database.database.delete_all_links(self,
342
+ Ink::Model.classname(k), v)
301
343
  end
302
344
  end
303
345
 
304
346
  pkvalue = instance_variable_get "@#{self.class.primary_key}"
305
- Ink::Database.database.remove self.class.name, "WHERE `#{self.class.primary_key}`=#{(pkvalue.is_a?(Numeric)) ? pkvalue : "\'#{pkvalue}\'"}"
347
+ Ink::Database.database.remove self.class.name, <<QUERY
348
+ WHERE `#{self.class.primary_key}`=#{
349
+ (pkvalue.is_a?(Numeric)) ? pkvalue : "\'#{pkvalue}\'"
350
+ }
351
+ QUERY
306
352
  end
307
353
 
308
354
  # Instance method
@@ -311,11 +357,15 @@ module Ink
311
357
  # matching foreign accessor
312
358
  # [param foreign_class:] Defines the foreign class name or class
313
359
  def find_references(foreign_class)
314
- c = (foreign_class.is_a? Class) ? foreign_class : Ink::Model.classname(foreign_class)
360
+ c = (foreign_class.is_a? Class) ? foreign_class :
361
+ Ink::Model.classname(foreign_class)
315
362
  relationship = self.class.foreign[c.class_name]
316
363
  if relationship
317
- 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)
318
- instance_variable_set("@#{c.table_name}", (relationship =~ /^one_/) ? result_array.first : result_array)
364
+ result_array = (relationship == "many_many") ?
365
+ Ink::Database.database.find_union(self.class, self.pk, c) :
366
+ Ink::Database.database.find_references(self.class, self.pk, c)
367
+ instance_variable_set("@#{c.table_name}",
368
+ (relationship =~ /^one_/) ? result_array.first : result_array)
319
369
  true
320
370
  else
321
371
  false
@@ -330,7 +380,11 @@ module Ink
330
380
  # [returns:] Array of SQL statements
331
381
  def self.create
332
382
  result = Array.new
333
- raise NotImplementedError.new("Cannot create a Database without field definitions") if not self.respond_to? :fields
383
+ if not self.respond_to?(:fields)
384
+ raise NotImplementedError.new(<<ERR)
385
+ Cannot create a Database without field definitions
386
+ ERR
387
+ end
334
388
 
335
389
  string = "CREATE TABLE #{self.table_name} ("
336
390
  mfk = self.foreign_key
@@ -346,7 +400,12 @@ module Ink
346
400
  tmp = self.foreign.map do |k,v|
347
401
  f_class = Ink::Model::classname(k)
348
402
  if v == "many_many" and (self.name <=> k) < 0
349
- 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});"
403
+ result.push <<QUERY
404
+ CREATE TABLE #{self.table_name}_#{Ink::Model::str_to_tablename(k)}
405
+ (#{Ink::Database.database.primary_key_autoincrement*" "},
406
+ `#{self.foreign_key}` #{self.foreign_key_type},
407
+ `#{f_class.foreign_key}` #{f_class.foreign_key_type});
408
+ QUERY
350
409
  nil
351
410
  end
352
411
  if v == "one_many" or (v == "one_one" and (self.name <=> k) < 0)
@@ -387,9 +446,12 @@ module Ink
387
446
  def self.str_to_classname(str)
388
447
  res = []
389
448
  str.scan(/((^|_)([a-z0-9]+))/) { |s|
390
- res.push(s[2][0].upcase + ((s[2].length > 1) ? s[2][1,s[2].length] : "")) if s.length > 0
449
+ if s.length > 0
450
+ res.push(s[2][0].upcase +
451
+ ((s[2].length > 1) ? s[2][1,s[2].length] : ""))
452
+ end
391
453
  }
392
- ((Module.const_get res.join).is_a? Class) ? res.join : nil
454
+ Module.const_get(res.join).is_a?(Class) ? res.join : nil
393
455
  end
394
456
 
395
457
  # Class method
@@ -404,7 +466,7 @@ module Ink
404
466
  str.scan(/([A-Z][a-z0-9]*)/) { |s|
405
467
  res.push (res.length>0) ? "_" + s.join.downcase : s.join.downcase
406
468
  }
407
- ((Module.const_get str).is_a? Class) ? res.join : nil
469
+ Module.const_get(str).is_a?(Class) ? res.join : nil
408
470
  end
409
471
 
410
472
  # Class method
@@ -418,12 +480,15 @@ module Ink
418
480
  res = []
419
481
  if str[0] =~ /^[a-z]/
420
482
  str.scan(/((^|_)([a-z0-9]+))/) { |s|
421
- res.push(s[2][0].upcase + ((s[2].length > 1) ? s[2][1,s[2].length] : "")) if s.length > 0
483
+ if s.length > 0
484
+ res.push(s[2][0].upcase +
485
+ ((s[2].length > 1) ? s[2][1,s[2].length] : ""))
486
+ end
422
487
  }
423
488
  else
424
489
  res.push str
425
490
  end
426
- ((Module.const_get res.join).is_a? Class) ? (Module.const_get res.join) : nil
491
+ Module.const_get(res.join).is_a?(Class) ? Module.const_get(res.join) : nil
427
492
  end
428
493
 
429
494
  # Class method
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.1.1
4
+ version: 3.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,16 +9,16 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-16 00:00:00.000000000 Z
12
+ date: 2013-06-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: fcgi
15
+ name: rack
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 0.8.8
21
+ version: 1.5.2
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,28 +26,12 @@ dependencies:
26
26
  requirements:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: 0.8.8
30
- - !ruby/object:Gem::Dependency
31
- name: simple-mmap
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ! '>='
36
- - !ruby/object:Gem::Version
37
- version: 1.1.4
38
- type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: 1.1.4
29
+ version: 1.5.2
46
30
  description:
47
31
  email:
48
32
  executables:
49
33
  - webink_database
50
- - rfcgi
34
+ - webink_init
51
35
  extensions: []
52
36
  extra_rdoc_files: []
53
37
  files:
@@ -57,7 +41,7 @@ files:
57
41
  - lib/webink/database.rb
58
42
  - lib/webink/model.rb
59
43
  - bin/webink_database
60
- - bin/rfcgi
44
+ - bin/webink_init
61
45
  - LICENSE.md
62
46
  homepage: https://github.com/matthias-geier/WebInk
63
47
  licenses: []
data/bin/rfcgi DELETED
@@ -1,143 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "fcgi"
4
- require "simple_mmap"
5
- require "webink/beauty"
6
-
7
- def getBinding(cgi,env,params)
8
- return binding
9
- end
10
- def error(cgi, code)
11
- puts cgi.header
12
- puts cgi.header("nph" => true, "status" => code, "connection" => "close", "type" => "text/html")
13
- end
14
-
15
- script = nil
16
- fhandle = nil
17
- control = nil
18
- pram = nil
19
- is_production = nil
20
- use_errors = nil
21
- FCGI.each_cgi do |cgi|
22
- is_production = ((cgi.env_table["INK_PRODUCTION"] and eval cgi.env_table["INK_PRODUCTION"]) or (ENV["INK_PRODUCTION"] and eval ENV["INK_PRODUCTION"])) ? true : false
23
- use_errors = ((cgi.env_table["INK_ERRORS"] and eval cgi.env_table["INK_ERRORS"]) or (ENV["INK_ERRORS"] and eval ENV["INK_ERRORS"])) ? true : false
24
- time = Time.now
25
- script = cgi.env_table['SCRIPT_FILENAME']
26
- begin
27
- pram = Hash.new
28
- CGI::parse(cgi.env_table['QUERY_STRING'].gsub(/\?/, "&")).each do |k,v|
29
- if v.is_a? Array
30
- if v.length == 0
31
- pram[k] = nil
32
- elsif v.length == 1
33
- pram[k] = v[0]
34
- else
35
- pram[k] = v
36
- end
37
- else
38
- pram[k] = v
39
- end
40
- end
41
- control = pram['controller']
42
- routes = Ink::Beauty.load_routes script
43
- fhandle = SimpleMmap::MappedFile.new(routes)
44
- Dir.chdir( File.dirname(routes) )
45
- control = eval fhandle.read_window_data(0,fhandle.size), getBinding(cgi,cgi.env_table,control) if fhandle
46
- fhandle.close
47
- raise StandardError.new("Routes not matched.") if control.keys.length <= 1
48
-
49
- control[:get] = pram
50
- control[:config] = Ink::Beauty.load_config script
51
- control[:time] = time
52
- control[:cgi] = cgi
53
- control[:env] = ENV
54
- control[:is_production] = is_production
55
- control[:use_errors] = use_errors
56
- if cgi.env_table['REQUEST_METHOD'] == 'POST'
57
- control[:post] = Hash.new
58
- cgi.params.each do |k,v|
59
- if v.is_a? Array
60
- control[:post][k] = Array.new
61
- v.each do |a|
62
- control[:post][k].push((control[:config]["escape_post_data"]) ? CGI::escapeHTML(a) : a)
63
- end
64
- control[:post][k] = control[:post][k][0] if control[:post][k].length <= 1
65
- else
66
- control[:post][k] = (control[:config]["escape_post_data"]) ? CGI::escapeHTML(v) : v
67
- end
68
- end
69
- pram.each do |k,v|
70
- cgi.params[k] = v if not cgi.params.has_key? k
71
- end
72
- else
73
- cgi.params = pram
74
- end
75
-
76
- script = Ink::Beauty.load_init script
77
- fhandle = SimpleMmap::MappedFile.new(script)
78
- Dir.chdir( File.dirname(script) )
79
- eval fhandle.read_window_data(0,fhandle.size), getBinding(cgi,cgi.env_table,control) if fhandle
80
- fhandle.close
81
-
82
- rescue LoadError => bang
83
- if is_production
84
- puts cgi.header({"Location" => "/status-404.html"}) if use_errors
85
- error cgi, "NOT_FOUND" if not use_errors
86
- else
87
- puts cgi.header
88
- puts "<hr><b>LoadError:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
89
- end
90
-
91
- rescue NotImplementedError => bang
92
- if is_production
93
- puts cgi.header({"Location" => "/status-500.html"}) if use_errors
94
- error cgi, "SERVER_ERROR" if not use_errors
95
- else
96
- puts cgi.header
97
- puts "<hr><b>NotImplementedError:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
98
- end
99
-
100
- rescue ArgumentError => bang
101
- if is_production
102
- puts cgi.header({"Location" => "/status-500.html"}) if use_errors
103
- error cgi, "SERVER_ERROR" if not use_errors
104
- else
105
- puts cgi.header
106
- puts "<hr><b>ArgumentError:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
107
- end
108
-
109
- rescue RuntimeError => bang
110
- if is_production
111
- puts cgi.header({"Location" => "/status-500.html"}) if use_errors
112
- error cgi, "SERVER_ERROR" if not use_errors
113
- else
114
- puts cgi.header
115
- puts "<hr><b>RuntimeError:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
116
- end
117
-
118
- rescue NameError => bang
119
- if is_production
120
- puts cgi.header({"Location" => "/status-500.html"}) if use_errors
121
- error cgi, "SERVER_ERROR" if not use_errors
122
- else
123
- puts cgi.header
124
- puts "<hr><b>NameError:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
125
- end
126
-
127
- rescue Exception, StandardError => bang
128
- if is_production
129
- puts cgi.header({"Location" => "/status-500.html"}) if use_errors
130
- error cgi, "SERVER_ERROR" if not use_errors
131
- else
132
- puts cgi.header
133
- puts "<hr><b>Exception:</b>", "<em><pre>", CGI::escapeHTML("#{bang}"), "</pre></em>\n", "<pre>", bang.backtrace.join("\n"), "</pre>"
134
- end
135
- end
136
-
137
- script = nil
138
- fhandle = nil
139
- control = nil
140
- pram = nil
141
- GC.start
142
- end
143
-