webink 2.1.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
-