nitro 0.7.0 → 0.8.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.
Files changed (102) hide show
  1. data/AUTHORS +14 -4
  2. data/ChangeLog +192 -1
  3. data/README +50 -6
  4. data/RELEASES +60 -0
  5. data/Rakefile +1 -1
  6. data/bin/cluster.rb +2 -2
  7. data/bin/new_form.rb +1 -1
  8. data/examples/blog/config.rb +5 -4
  9. data/examples/blog/lib/blog.rb +56 -36
  10. data/examples/blog/root/comments.xhtml +5 -2
  11. data/examples/blog/root/entry_form.xhtml +7 -2
  12. data/examples/blog/root/login.xhtml +1 -1
  13. data/examples/blog/root/style.xsl +7 -0
  14. data/examples/og/mock_example.rb +6 -9
  15. data/examples/og/mysql_to_psql.rb +100 -0
  16. data/examples/og/run.rb +8 -17
  17. data/lib/glue.rb +7 -8
  18. data/lib/glue/array.rb +1 -1
  19. data/lib/glue/attribute.rb +86 -0
  20. data/lib/glue/cache.rb +1 -1
  21. data/lib/glue/hash.rb +1 -1
  22. data/lib/glue/inflector.rb +1 -1
  23. data/lib/glue/logger.rb +118 -18
  24. data/lib/glue/mixins.rb +1 -1
  25. data/lib/glue/number.rb +1 -1
  26. data/lib/glue/pool.rb +1 -1
  27. data/lib/glue/property.rb +48 -31
  28. data/lib/glue/string.rb +1 -1
  29. data/lib/glue/time.rb +2 -2
  30. data/lib/glue/validation.rb +400 -0
  31. data/lib/nitro/application.rb +6 -6
  32. data/lib/nitro/builders/form.rb +5 -5
  33. data/lib/nitro/builders/rss.rb +1 -1
  34. data/lib/nitro/builders/xhtml.rb +119 -0
  35. data/lib/nitro/builders/xml.rb +111 -0
  36. data/lib/nitro/config.rb +6 -6
  37. data/lib/nitro/events.rb +1 -1
  38. data/lib/nitro/html.rb +1 -1
  39. data/lib/nitro/markup.rb +15 -20
  40. data/lib/nitro/scaffold.rb +2 -2
  41. data/lib/nitro/server/appserver.rb +3 -3
  42. data/lib/nitro/server/cluster.rb +2 -2
  43. data/lib/nitro/server/dispatcher.rb +2 -2
  44. data/lib/nitro/server/filters/autologin.rb +1 -1
  45. data/lib/nitro/server/fragment.rb +2 -2
  46. data/lib/nitro/server/handlers.rb +2 -2
  47. data/lib/nitro/server/render.rb +17 -15
  48. data/lib/nitro/server/request.rb +6 -6
  49. data/lib/nitro/server/script.rb +2 -2
  50. data/lib/nitro/server/server.rb +2 -2
  51. data/lib/nitro/server/session.rb +6 -6
  52. data/lib/nitro/server/shaders.rb +2 -2
  53. data/lib/nitro/server/webrick.rb +1 -1
  54. data/lib/nitro/sitemap.rb +2 -2
  55. data/lib/nitro/uri.rb +1 -1
  56. data/lib/nitro/version.rb +7 -5
  57. data/lib/og.rb +95 -129
  58. data/lib/og/backend.rb +47 -46
  59. data/lib/og/backends/mysql.rb +64 -63
  60. data/lib/og/backends/psql.rb +73 -72
  61. data/lib/og/connection.rb +7 -8
  62. data/lib/og/enchant.rb +80 -0
  63. data/lib/og/meta.rb +21 -21
  64. data/lib/og/mock.rb +31 -88
  65. data/lib/og/version.rb +6 -5
  66. data/lib/parts/README +9 -0
  67. data/lib/parts/content.rb +23 -9
  68. data/test/glue/tc_attribute.rb +22 -0
  69. data/test/glue/tc_cache.rb +4 -6
  70. data/test/glue/tc_hash.rb +2 -2
  71. data/test/glue/tc_logger.rb +36 -0
  72. data/test/glue/tc_numbers.rb +2 -2
  73. data/test/glue/tc_property_mixins.rb +35 -4
  74. data/test/glue/tc_strings.rb +32 -32
  75. data/test/glue/tc_validation.rb +186 -0
  76. data/test/nitro/builders/tc_xhtml.rb +38 -0
  77. data/test/nitro/builders/tc_xml.rb +47 -0
  78. data/test/nitro/server/tc_request.rb +2 -2
  79. data/test/nitro/server/tc_session.rb +1 -1
  80. data/test/nitro/tc_sitemap.rb +1 -1
  81. data/test/nitro/ui/tc_pager.rb +1 -10
  82. data/test/tc_og.rb +3 -3
  83. data/vendor/blankslate.rb +53 -0
  84. data/vendor/extensions/_base.rb +153 -0
  85. data/vendor/extensions/_template.rb +36 -0
  86. data/vendor/extensions/all.rb +21 -0
  87. data/vendor/extensions/array.rb +68 -0
  88. data/vendor/extensions/binding.rb +224 -0
  89. data/vendor/extensions/class.rb +50 -0
  90. data/vendor/extensions/continuation.rb +71 -0
  91. data/vendor/extensions/enumerable.rb +250 -0
  92. data/vendor/extensions/hash.rb +23 -0
  93. data/vendor/extensions/io.rb +58 -0
  94. data/vendor/extensions/kernel.rb +42 -0
  95. data/vendor/extensions/module.rb +114 -0
  96. data/vendor/extensions/numeric.rb +230 -0
  97. data/vendor/extensions/object.rb +164 -0
  98. data/vendor/extensions/ostruct.rb +41 -0
  99. data/vendor/extensions/string.rb +316 -0
  100. data/vendor/extensions/symbol.rb +28 -0
  101. metadata +35 -13
  102. data/lib/glue/property.rb.old +0 -307
@@ -73,7 +73,7 @@ class Cluster < N::Application
73
73
  begin
74
74
  sdrb.server_sync(key, value)
75
75
  rescue => ex
76
- $log.error "Server at #{uri} is down, removing from cluster"
76
+ Logger.error "Server at #{uri} is down, removing from cluster"
77
77
  cluster.delete(uri)
78
78
  end
79
79
  }
@@ -94,7 +94,7 @@ class Cluster < N::Application
94
94
  begin
95
95
  sdrb.server_sync(key, value) unless uri == server_uri
96
96
  rescue => ex
97
- $log.error "Server at #{uri} is down, removing from cluster"
97
+ Logger.error "Server at #{uri} is down, removing from cluster"
98
98
  cluster.delete(uri)
99
99
  end
100
100
  }
@@ -22,8 +22,8 @@ module Dispatcher
22
22
  render(request.request_uri.path, request, response, session)
23
23
  response.body = @out
24
24
  rescue Exception, StandardError => e
25
- $log.error "error while handling the request #{request.request_uri}"
26
- $log.error pp_exception(e)
25
+ Logger.error "error while handling the request #{request.request_uri}"
26
+ Logger.error pp_exception(e)
27
27
 
28
28
  if $error_page_url
29
29
  # gmosx: SOS: TEST ME!
@@ -38,7 +38,7 @@ class AutoLoginFilter < N::ServerFilter
38
38
  request.del_cookie($users_auth_cookie)
39
39
  end
40
40
  else
41
- $log.warn "Unknown user or wrong password in auth-cookie: #{cookie} from IP: #{request.remote_addr}"
41
+ Logger.warn "Unknown user or wrong password in auth-cookie: #{cookie} from IP: #{request.remote_addr}"
42
42
  end
43
43
  end
44
44
  end
@@ -28,8 +28,8 @@ module N
28
28
  # - can run background cron scripts over the fragments (compression)
29
29
  #
30
30
  class Fragment
31
- include G::Expirable
32
- include G::LRUCache::Item
31
+ include N::Expirable
32
+ include N::LRUCache::Item
33
33
 
34
34
  # precompiled flags for fragment key "customization"
35
35
 
@@ -50,7 +50,7 @@ class ScriptHandler < Handler
50
50
 
51
51
  # cache the compiled page scripts to optimize future references.
52
52
  # use a thread safe cache.
53
- @@compiled_script_cache = G::SafeHash.new()
53
+ @@compiled_script_cache = N::SafeHash.new()
54
54
 
55
55
  # dont allow 2 threads to compile the same script. In fact dont allow
56
56
  # two threads to compile in parallel.
@@ -65,7 +65,7 @@ class ScriptHandler < Handler
65
65
  if ::File.exists?("#$root_dir/#{path}")
66
66
  return path
67
67
  else
68
- $log.debug "OVERLOAD: '#{path}' -> 'p/#{path}'" if $DBG
68
+ Logger.debug "OVERLOAD: '#{path}' -> 'p/#{path}'" if $DBG
69
69
  return "p/#{path}"
70
70
  end
71
71
  end
@@ -1,7 +1,5 @@
1
- # code:
2
- # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
1
+ # George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
5
3
  # $Id: render.rb 200 2004-12-27 11:24:41Z gmosx $
6
4
 
7
5
  require 'cgi'
@@ -11,19 +9,19 @@ module N
11
9
  # = RenderUtils
12
10
  #
13
11
  # Various render related utilities.
14
- #
12
+
15
13
  module RenderUtils
16
14
 
17
15
  # Split the path to base, render_class and method.
18
16
  #
19
- # Examples:
17
+ # == Examples
20
18
  #
21
19
  # / -> nil, index, nil
22
20
  # /add_user -> nil, add_user, nil
23
21
  # /add_user?user=gmosx -> nil, add_user, user=gmosx
24
22
  # /blog/new_entry -> blog, new_entry
25
23
  # /blog -> blog, index, nil
26
- #
24
+
27
25
  def self.split_path(path)
28
26
  # paths that start with rest/xxx are REST requests.
29
27
  # FIXME: better chack here!
@@ -86,7 +84,7 @@ module RenderUtils
86
84
  # Transform a template to ruby rendering code.
87
85
  #
88
86
  def self.transform_template(path)
89
- $log.debug "Transforming '#{path}'" if $DBG
87
+ Logger.debug "Transforming '#{path}'" if $DBG
90
88
 
91
89
  text = File.read(path)
92
90
  hash, text = $shader.process(path, text)
@@ -98,7 +96,7 @@ module RenderUtils
98
96
  # Compile a HTTP method.
99
97
  #
100
98
  def self.compile_http_method(klass, base, meth)
101
- $log.debug "Compiling HTTP method '#{klass}:#{meth}'" if $DBG
99
+ Logger.debug "Compiling HTTP method '#{klass}:#{meth}'" if $DBG
102
100
 
103
101
  valid = false
104
102
 
@@ -173,7 +171,7 @@ module RenderUtils
173
171
  # Compile a REST method.
174
172
  #
175
173
  def self.compile_rest_method(klass, base, meth)
176
- $log.debug "Compiling REST method '#{klass}:#{meth}'" if $DBG
174
+ Logger.debug "Compiling REST method '#{klass}:#{meth}'" if $DBG
177
175
 
178
176
  valid = false
179
177
 
@@ -250,12 +248,12 @@ end
250
248
  # = RenderExit
251
249
  #
252
250
  # Raise this exception to stop rendering.
253
- #
251
+
254
252
  class RenderExit < Exception
255
253
  end
256
254
 
257
255
  # = Render
258
- #
256
+
259
257
  module Render
260
258
  # The outbut buffer. The output of a script/action is accumulated
261
259
  # in this buffer.
@@ -321,9 +319,12 @@ module Render
321
319
  if self.class == render_class
322
320
  self.send(meth)
323
321
  else
322
+ =begin
323
+ gmosx: reolading fucks up validation and meta data propagation.
324
324
  if $reload_scripts and defined?(render_class::SOURCE_FILE)
325
325
  load(render_class::SOURCE_FILE)
326
326
  end
327
+ =end
327
328
  r = render_class.new(base, @request, @response, @session)
328
329
  r.send(meth)
329
330
  @out = r.out
@@ -362,8 +363,8 @@ module Render
362
363
 
363
364
  # Redirect to the referer of this method.
364
365
  #
365
- def redirect_referer(status = 303)
366
- redirect(@request.referer, status)
366
+ def redirect_referer(postfix = nil, status = 303)
367
+ redirect("#{@request.referer}#{postfix}", status)
367
368
  end
368
369
 
369
370
  # Log a rendering error.
@@ -373,7 +374,7 @@ module Render
373
374
  def log_error(str)
374
375
  @rendering_errors ||= []
375
376
  @rendering_errors << str
376
- $log.error str
377
+ Logger.error str
377
378
  end
378
379
 
379
380
  # --------------------------------------------------------------------
@@ -400,6 +401,7 @@ module Render
400
401
  @out = @out_buffers.pop
401
402
  @out << nested_buffer
402
403
  end
404
+
403
405
  # --------------------------------------------------------------------
404
406
  # Caching methods.
405
407
 
@@ -68,7 +68,7 @@ module RequestUtils
68
68
  return obj
69
69
  end
70
70
  else
71
- # $log.error "request.get_object('#{oid_param}') failed!"
71
+ # Logger.error "request.get_object('#{oid_param}') failed!"
72
72
  return nil
73
73
  end
74
74
  end
@@ -89,7 +89,7 @@ module RequestUtils
89
89
  return nil
90
90
  end
91
91
  else
92
- # $log.error "request.get_object_by_name('#{name_param}') failed!"
92
+ # Logger.error "request.get_object_by_name('#{name_param}') failed!"
93
93
  return obj
94
94
  end
95
95
  else
@@ -352,7 +352,7 @@ class Request
352
352
  def get(key, default=nil)
353
353
  val = @parameters[key]
354
354
 
355
- if !val or (val.is_a?(String) and (not G::StringUtils.valid?(val)))
355
+ if !val or (val.is_a?(String) and (not N::StringUtils.valid?(val)))
356
356
  @parameters[key] = default
357
357
  return default
358
358
  elsif default.is_a?(Integer)
@@ -429,7 +429,7 @@ class Request
429
429
  # Check if a parameter is valid
430
430
  #
431
431
  def param?(param)
432
- return G::StringUtils.valid?(self[param])
432
+ return N::StringUtils.valid?(self[param])
433
433
  end
434
434
  alias_method :action?, :param?
435
435
 
@@ -465,7 +465,7 @@ class Request
465
465
  end
466
466
 
467
467
  # gmosx: to avoid using param?
468
- if param.is_a?(String) and (not G::StringUtils.valid?(param))
468
+ if param.is_a?(String) and (not N::StringUtils.valid?(param))
469
469
  return nil
470
470
  else
471
471
  return param
@@ -547,7 +547,7 @@ class Request
547
547
  def log_error(str)
548
548
  @error_log = [] unless @error_log
549
549
  @error_log << str if @error_log.size < 200 # gmosx: dod attack!
550
- $log.error str
550
+ Logger.error str
551
551
  end
552
552
 
553
553
  # ====================================================================
@@ -63,7 +63,7 @@ class Script
63
63
 
64
64
  # sub-scripts set: a set of files this script depends on.
65
65
  # We use a hash to implement a set.
66
- @sub_scripts = G::SafeArray.new
66
+ @sub_scripts = N::SafeArray.new
67
67
 
68
68
  # a cache for the script outputs (fragments). Keeps multiple revisions
69
69
  # of the script output according to user, access rights etc.
@@ -74,7 +74,7 @@ class Script
74
74
  #
75
75
  # DISK CACHING IS SLOW!
76
76
  #
77
- @fragment_cache = G::LRUCache.new(1000)
77
+ @fragment_cache = N::LRUCache.new(1000)
78
78
 
79
79
  __init()
80
80
  end
@@ -25,7 +25,7 @@ module ServerMixin
25
25
  $sessions = DRbObject.new(nil, $drb_sessions_cluster)
26
26
  else
27
27
  # NoCluster mode: use standard Ruby onjects.
28
- $lm = G::SafeHash.new
28
+ $lm = N::SafeHash.new
29
29
  $sessions = N::App::SessionManager.new
30
30
  end
31
31
 
@@ -50,7 +50,7 @@ class Server < N::Server
50
50
  super
51
51
  initialize_app()
52
52
 
53
- $log.info "Server listening at #$srv_url"
53
+ Logger.info "Server listening at #$srv_url"
54
54
  end
55
55
  end
56
56
 
@@ -23,13 +23,13 @@ module N
23
23
  #
24
24
  # SOS: This object lives in the Cluster!
25
25
  #
26
- class SessionManager < G::SafeHash
26
+ class SessionManager < N::SafeHash
27
27
  # the collection of online users.
28
28
  attr_reader :online
29
29
 
30
30
  def initialize
31
31
  super
32
- @online = G::SafeHash.new
32
+ @online = N::SafeHash.new
33
33
  end
34
34
 
35
35
  # Return the number of anonymous sessions.
@@ -80,12 +80,12 @@ class SessionManager < G::SafeHash
80
80
  begin
81
81
  session = $sessions[key]
82
82
  if session.stale?
83
- $log.debug "Session finalized: logging out idle user '#{session.user}'" if $DBG
83
+ Logger.debug "Session finalized: logging out idle user '#{session.user}'" if $DBG
84
84
  session.logout()
85
85
  $sessions.delete(key)
86
86
  end
87
87
  rescue Exception, StandardError => e
88
- $log.error "Session gc errror #$!"
88
+ Logger.error "Session gc errror #$!"
89
89
  end
90
90
  end
91
91
  end
@@ -138,7 +138,7 @@ class Session < Hash
138
138
  @user = user
139
139
  @user.login(request)
140
140
  $sessions.login(@user.oid, @user.name)
141
- $log.info "User '#{user}' logged in!"
141
+ Logger.info "User '#{user}' logged in!"
142
142
  return true
143
143
  end
144
144
 
@@ -148,7 +148,7 @@ class Session < Hash
148
148
  self.clear()
149
149
  @user.logout()
150
150
  $sessions.logout(@user.oid)
151
- $log.info "User '#{user}' logged out!"
151
+ Logger.info "User '#{user}' logged out!"
152
152
  @user = N::AnonymousUser.instance
153
153
  end
154
154
 
@@ -122,7 +122,7 @@ class RubyShader < N::Shader
122
122
  # Loads and statically includes a file.
123
123
  #
124
124
  def load_statically_included(filename)
125
- $log.debug "Statically including '#{filename}'" if $DBG
125
+ Logger.debug "Statically including '#{filename}'" if $DBG
126
126
 
127
127
  text = File.read(filename)
128
128
  text.gsub!(/<\?xml.*\?>/, '')
@@ -176,7 +176,7 @@ class XSLTShader < N::Shader
176
176
  # Parse the xsl.
177
177
  #
178
178
  def parse_xsl
179
- $log.debug "Parsing xsl '#{@xsl_filename}'" if $DBG
179
+ Logger.debug "Parsing xsl '#{@xsl_filename}'" if $DBG
180
180
  @mtime = File.mtime(@xsl_filename)
181
181
  @xslt.xsl = File.read(@xsl_filename)
182
182
  end
@@ -164,7 +164,7 @@ class WebrickDispatcher < WEBrick::HTTPServlet::AbstractServlet
164
164
  end
165
165
 
166
166
  unless session
167
- $log.debug 'Creating new session.' if $DBG
167
+ Logger.debug 'Creating new session.' if $DBG
168
168
  # no session cookie or stale session (garbage collected).
169
169
  session_id = N::Session.calculate_id()
170
170
  cookie = WEBrick::Cookie.new(N::Session::COOKIE_NAME, session_id)
@@ -85,7 +85,7 @@ end
85
85
  # - Use a second class in the UI namespace for rendering
86
86
  # related stuff?
87
87
  #
88
- class SiteMap < G::SafeHash
88
+ class SiteMap < N::SafeHash
89
89
 
90
90
  # The root page for this sitemap
91
91
  attr_accessor :root
@@ -121,7 +121,7 @@ class SiteMap < G::SafeHash
121
121
 
122
122
  return res
123
123
  else
124
- $log.warn "The uri #{uri} is not registered in the SiteMap!"
124
+ Logger.warn "The uri #{uri} is not registered in the SiteMap!"
125
125
  end
126
126
 
127
127
  return nil
@@ -165,7 +165,7 @@ module UriUtils
165
165
  hash.update(parameters)
166
166
  query_string = self.hash_to_query_string(hash)
167
167
 
168
- if G::StringUtils.valid?(query_string)
168
+ if N::StringUtils.valid?(query_string)
169
169
  return "#{rest}?#{query_string}"
170
170
  else
171
171
  return rest
@@ -1,11 +1,13 @@
1
- # code:
2
- # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
1
+ #--
2
+ # George Moschovitis <gm@navel.gr>
3
+ # (c) 2004-2005 Navel, all rights reserved.
5
4
  # $Id: version.rb 194 2004-12-20 20:23:57Z gmosx $
5
+ #++
6
6
 
7
7
  # The name of the server.
8
+
8
9
  $srv_name = 'Nitro'
9
10
 
10
11
  # The version of the server.
11
- $srv_version = '0.7.0'
12
+
13
+ $srv_version = '0.8.0'
data/lib/og.rb CHANGED
@@ -4,36 +4,12 @@
4
4
  # (c) 2004 Navel, all rights reserved.
5
5
  # $Id: og.rb 197 2004-12-21 13:50:17Z gmosx $
6
6
 
7
- require "glue/property"
8
- require "glue/array"
9
- require "glue/hash"
10
- require "glue/time"
11
- require "glue/pool"
12
-
13
- # If true, only allow reading from the database. Usefull
14
- # for maintainance.
15
- #
16
- $og_read_only_mode = false
17
-
18
- # If true, the library automatically 'enchants' managed classes.
19
- # In enchant mode, special db aware methods are added to
20
- # managed classes and instances.
21
- #
22
- $og_enchant_managed_classes = true
23
-
24
- # If true, use Ruby's advanced introspection capabilities to
25
- # automatically manage classes tha define properties.
26
- $og_auto_manage_classes = true
27
-
28
- # If true, automatically include the Og meta-language into Module.
29
- $og_include_meta_language = true
30
-
31
- # Attach the following prefix to all generated SQL table names.
32
- # Usefull on hosting scenarios where you have to run multiple
33
- # web applications/sites on a single database.
34
- $og_table_prefix = nil
35
-
36
- require "og/meta"
7
+ require 'glue/logger'
8
+ require 'glue/property'
9
+ require 'glue/array'
10
+ require 'glue/hash'
11
+ require 'glue/time'
12
+ require 'glue/pool'
37
13
 
38
14
  # = Og
39
15
  #
@@ -58,11 +34,12 @@ require "og/meta"
58
34
  # + Transparent support for cascading deletes for all backends.
59
35
  # + Hierarchical structures (preorder traversal, materialized paths)
60
36
  # + Works safely as part of distributed application.
61
- # + Simple implementation < 2k lines of code.
37
+ # + Simple implementation.
62
38
  #
63
39
  # === Meta language
64
40
  #
65
- # primary_key :pid
41
+ # primary_key :pid (NOT IMPLEMENTED)
42
+ # name_key :name (NOT IMPLEMENTED)
66
43
  # prop_accessor Fixnum, :pid, :sql => "smallint DEFAULT 1"
67
44
  # has_many Child, :children
68
45
  # many_to_many Role, :roles
@@ -71,10 +48,10 @@ require "og/meta"
71
48
  # === Design
72
49
  #
73
50
  # Keep the main classes backend agnostic.
74
- #
51
+ #--
75
52
  # Try to make the methods work with oids. Do NOT implement descendants
76
53
  # use a root id (rid).
77
- #
54
+ #++
78
55
  # For class ids we use the name instead of a hash. Class ids are
79
56
  # typically not used in querys, they are stored for completeness.
80
57
  # If we store a hash we cannot reclaim the class thus invalidating
@@ -89,7 +66,7 @@ require "og/meta"
89
66
  # This is NOT a singleton, an application may access multiple
90
67
  # databases.
91
68
  #
92
- # The $og.xxx methods are more flexible and allow you to use
69
+ # The og.xxx methods are more flexible and allow you to use
93
70
  # multiple databases for example.
94
71
  #
95
72
  # === Managed Objects Lifecycle Callbacks
@@ -101,7 +78,6 @@ require "og/meta"
101
78
  # * og_pre_insert_update
102
79
  # * og_post_insert_update
103
80
  # * self.og_pre_delete
104
- # * validate
105
81
  #
106
82
  # A class level callback is used for delete because typically you call
107
83
  # delete with an oid and not an object to avoid a deserialization.
@@ -114,8 +90,53 @@ require "og/meta"
114
90
  # * Deserialize to OpenStruct.
115
91
  # * Better documentation.
116
92
  #
117
- module Og
93
+ class Og
94
+ class << self
95
+ # If true, only allow reading from the database. Usefull
96
+ # for maintainance.
97
+ attr_accessor :read_only_mode
98
+
99
+ # If true, the library automatically 'enchants' managed classes.
100
+ # In enchant mode, special db aware methods are added to
101
+ # managed classes and instances.
102
+ attr_accessor :enchant_managed_classes
103
+
104
+ # If true, use Ruby's advanced introspection capabilities to
105
+ # automatically manage classes tha define properties.
106
+ attr_accessor :auto_manage_classes
118
107
 
108
+ # If true, automatically include the Og meta-language into Module.
109
+ attr_accessor :include_meta_language
110
+
111
+ # Attach the following prefix to all generated SQL table names.
112
+ # Usefull on hosting scenarios where you have to run multiple
113
+ # web applications/sites on a single database.
114
+ attr_accessor :table_prefix
115
+
116
+ # The active database. Og allows you to access multiple
117
+ # databases from a single application.
118
+ attr_accessor :db
119
+
120
+ def use(db)
121
+ @db = db
122
+ @db.get_connection
123
+ end
124
+ end
125
+
126
+ # set default options:
127
+ self.read_only_mode = false
128
+ self.enchant_managed_classes = true
129
+ self.auto_manage_classes = true
130
+ self.include_meta_language = true
131
+ self.table_prefix = nil
132
+ end
133
+
134
+ # gmosx: leave this here.
135
+ require 'og/enchant'
136
+ require 'og/meta'
137
+
138
+ class Og
139
+
119
140
  # = Unmanageable
120
141
  #
121
142
  # Marker module. If included this in a class, the Og automanager
@@ -128,6 +149,7 @@ module Unmanageable; end
128
149
  # Encapsulates an Og Database.
129
150
  #
130
151
  class Database
152
+ include Og::Enchant
131
153
 
132
154
  # Managed class metadata
133
155
  #
@@ -166,10 +188,10 @@ class Database
166
188
  require "og/backends/#{backend}"
167
189
  eval %{ @config[:backend] = #{backend.capitalize}Backend }
168
190
 
169
- @connection_pool = G::Pool.new
170
- @managed_classes = G::SafeHash.new
191
+ @connection_pool = N::Pool.new
192
+ @managed_classes = N::SafeHash.new
171
193
 
172
- $log.info "Connecting to database '#{@config[:database]}' using backend '#{backend}'."
194
+ Logger.info "Connecting to database '#{@config[:database]}' using backend '#{backend}'."
173
195
 
174
196
  @config[:connection_count].times do
175
197
  @connection_pool << Og::Connection.new(self)
@@ -178,7 +200,7 @@ class Database
178
200
  # gmosx, FIXME: this automanage code is not elegant and slow
179
201
  # should probably recode this, along with glue/property.rb
180
202
  #
181
- if $og_auto_manage_classes
203
+ if Og.auto_manage_classes
182
204
  # automatically manage classes with properties and metadata.
183
205
  # gmosx: Any idea how to optimize this?
184
206
  classes_to_manage = []
@@ -187,10 +209,13 @@ class Database
187
209
  classes_to_manage << c
188
210
  end
189
211
  end
190
- $log.info "Og auto manages the following classes:"
191
- $log.info "#{classes_to_manage.inspect}"
212
+ Logger.info "Og auto manages the following classes:"
213
+ Logger.info "#{classes_to_manage.inspect}"
192
214
  manage_classes(*classes_to_manage)
193
215
  end
216
+
217
+ # use the newly created database.
218
+ Og.use(self)
194
219
  end
195
220
 
196
221
  # Shutdown the database interface.
@@ -206,8 +231,6 @@ class Database
206
231
  # Stores the connection in a thread-local variable.
207
232
  #
208
233
  def get_connection
209
- $log.debug "Get Og connection" if $DBG
210
-
211
234
  thread = Thread.current
212
235
 
213
236
  unless conn = thread[:og_conn]
@@ -217,12 +240,11 @@ class Database
217
240
 
218
241
  return conn
219
242
  end
243
+ alias_method :connection, :get_connection
220
244
 
221
245
  # Restore an unused connection to the pool.
222
246
  #
223
247
  def put_connection
224
- $log.debug "Put Og connection" if $DBG
225
-
226
248
  thread = Thread.current
227
249
 
228
250
  if conn = thread[:og_conn]
@@ -263,7 +285,7 @@ class Database
263
285
  convert(klass)
264
286
 
265
287
  # Add helper methods to the class.
266
- enchant(klass) if $og_enchant_managed_classes
288
+ enchant(klass) if Og.enchant_managed_classes
267
289
  end
268
290
 
269
291
  # Helper method to set multiple managed classes.
@@ -289,13 +311,16 @@ class Database
289
311
  # Add standard og functionality to the class
290
312
  #
291
313
  def convert(klass)
314
+ # Grab backend class
315
+ backend = @config[:backend]
316
+
292
317
  # gmosx: this check is needed to allow the developer to customize
293
318
  # the sql generated for oid
294
- Og::Utils.eval_og_oid(klass) unless klass.instance_methods.include?(:oid)
319
+ backend.eval_og_oid(klass) unless klass.instance_methods.include?(:oid)
295
320
 
296
321
  klass.class_eval %{
297
- DBTABLE = "#{Og::Utils.table(klass)}"
298
- DBSEQ = "#{Og::Utils.table(klass)}_oids_seq"
322
+ DBTABLE = "#{backend.table(klass)}"
323
+ DBSEQ = "#{backend.table(klass)}_oids_seq"
299
324
 
300
325
  def to_i()
301
326
  @oid
@@ -308,72 +333,9 @@ class Database
308
333
  # Precompile some code that gets executed all the time.
309
334
  # Deletion code is not precompiled, because it is not used
310
335
  # as frequently.
311
- Og::Utils.eval_og_insert(klass)
312
- Og::Utils.eval_og_update(klass)
313
- Og::Utils.eval_og_deserialize(klass, self)
314
- end
315
-
316
- # Enchant a managed class. Add useful DB related methods to the
317
- # class and its instances.
318
- #
319
- def enchant(klass)
320
- klass.module_eval <<-"end_eval", __FILE__, __LINE__
321
- def self.create(*params)
322
- obj = #{klass}.new(*params)
323
- obj.save!
324
- end
325
-
326
- def self.save(obj)
327
- $og << obj
328
- end
329
-
330
- def self.load(oid_or_name)
331
- $og.load(oid_or_name, #{klass})
332
- end
333
-
334
- def self.[](oid_or_name)
335
- $og.load(oid_or_name, #{klass})
336
- end
337
-
338
- def self.load_all(extra_sql = nil)
339
- $og.load_all(#{klass}, extra_sql)
340
- end
341
-
342
- def self.all(extra_sql = nil)
343
- $og.load_all(#{klass}, extra_sql)
344
- end
345
-
346
- def self.count(sql = "SELECT COUNT(*) FROM #{klass::DBTABLE}")
347
- $og.count(sql, #{klass})
348
- end
349
-
350
- def self.select(sql)
351
- $og.select(sql, #{klass})
352
- end
353
-
354
- def self.select_one(sql)
355
- $og.select_one(sql, #{klass})
356
- end
357
-
358
- def self.delete(obj_or_oid)
359
- $og.delete(obj_or_oid, #{klass})
360
- end
361
-
362
- def save
363
- $og << self
364
- return self
365
- end
366
- alias_method :save!, :save
367
-
368
- def update_properties(updatesql)
369
- $og.pupdate(updatesql, self.oid, #{klass})
370
- end
371
- alias_method :pupdate!, :update_properties
372
-
373
- def delete!
374
- $og.delete(@oid, #{klass})
375
- end
376
- end_eval
336
+ backend.eval_og_insert(klass)
337
+ backend.eval_og_update(klass)
338
+ backend.eval_og_deserialize(klass, self)
377
339
  end
378
340
 
379
341
  # Automatically wrap connection methods.
@@ -412,19 +374,23 @@ class Database
412
374
  wrap_method :query, "sql"
413
375
  wrap_method :exec, "sql"
414
376
 
415
- def self.create_db!(config)
416
- get_connection().db.create_db(config[:database], config[:user],
417
- config[:password])
418
- end
419
-
420
- def self.drop_db!(config)
421
- backend = config[:backend] || "psql"
422
- require "og/backends/#{backend}"
423
- eval %{
424
- #{backend.capitalize}Backend.drop_db(config[:database], config[:user],
377
+ class << self
378
+ def create_db!(config)
379
+ get_connection().db.create_db(config[:database], config[:user],
425
380
  config[:password])
426
- }
381
+ end
382
+ alias_method :create!, :create_db!
383
+
384
+ def drop_db!(config)
385
+ backend = config[:backend] || "psql"
386
+ require "og/backends/#{backend}"
387
+ eval %{
388
+ #{backend.capitalize}Backend.drop_db(config[:database], config[:user],
389
+ config[:password])
390
+ }
391
+ end
392
+ alias_method :drop!, :drop_db!
427
393
  end
428
394
  end
429
395
 
430
- end # module
396
+ end # namespace