nitro 0.2.0 → 0.3.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 (76) hide show
  1. data/ChangeLog +186 -0
  2. data/README +40 -11
  3. data/RELEASES +10 -1
  4. data/Rakefile +5 -4
  5. data/bin/cluster.rb +3 -3
  6. data/{etc/new-project.rb → bin/new_app.rb} +1 -1
  7. data/examples/og/README +4 -0
  8. data/examples/og/run.rb +254 -0
  9. data/examples/simple/app.rb +3 -3
  10. data/examples/simple/conf/config.rb +10 -22
  11. data/examples/simple/conf/debug-config.rb +6 -32
  12. data/examples/simple/conf/live-config.rb +3 -23
  13. data/examples/simple/conf/requires.rb +5 -5
  14. data/examples/simple/env.rb +3 -4
  15. data/examples/simple/lib/articles/entities.rb +17 -15
  16. data/examples/simple/lib/articles/methods.rb +15 -15
  17. data/examples/simple/lib/articles/part.rb +7 -8
  18. data/examples/simple/root/comments.si +1 -1
  19. data/examples/simple/root/index.sx +1 -1
  20. data/examples/simple/root/view-article.sx +1 -2
  21. data/examples/tiny/app.rb +3 -3
  22. data/examples/tiny/conf/config.rb +4 -4
  23. data/examples/tiny/conf/requires.rb +3 -4
  24. data/lib/n/config.rb +50 -3
  25. data/lib/n/logger.rb +14 -2
  26. data/lib/n/og.rb +381 -0
  27. data/lib/n/og/backend.rb +252 -0
  28. data/lib/n/og/backends/mysql.rb +352 -0
  29. data/lib/n/og/backends/psql.rb +351 -0
  30. data/lib/n/og/connection.rb +253 -0
  31. data/lib/n/og/meta.rb +127 -0
  32. data/lib/n/properties.rb +6 -6
  33. data/lib/n/server.rb +4 -7
  34. data/lib/n/server/appserver.rb +58 -0
  35. data/lib/n/{app → server}/cluster.rb +3 -3
  36. data/lib/n/{app → server}/cookie.rb +3 -3
  37. data/lib/n/server/dispatcher.rb +55 -0
  38. data/lib/n/server/{filter.rb → filters.rb} +1 -1
  39. data/lib/n/{app → server}/filters/autologin.rb +5 -5
  40. data/lib/n/{app → server}/fragment.rb +3 -3
  41. data/lib/n/{app → server}/handlers.rb +4 -4
  42. data/lib/n/{app → server}/handlers/code-handler.rb +6 -6
  43. data/lib/n/{app → server}/handlers/page-handler.rb +9 -7
  44. data/lib/n/{app → server}/request.rb +8 -8
  45. data/lib/n/{app/request-part.rb → server/requestpart.rb} +4 -4
  46. data/lib/n/{app → server}/script.rb +5 -5
  47. data/lib/n/{app → server}/server.rb +1 -1
  48. data/lib/n/{app → server}/session.rb +5 -5
  49. data/lib/n/{app → server}/user.rb +1 -1
  50. data/lib/n/{app/webrick-servlet.rb → server/webrick.rb} +77 -20
  51. data/lib/n/shaders.rb +3 -2
  52. data/lib/n/std.rb +5 -32
  53. data/test/n/{app → server}/tc_cookie.rb +2 -2
  54. data/test/n/server/tc_filters.rb +38 -0
  55. data/test/n/{app → server}/tc_request.rb +6 -6
  56. data/test/n/{app → server}/tc_requestpart.rb +3 -3
  57. data/test/n/{app → server}/tc_session.rb +2 -2
  58. data/test/n/tc_og.rb +178 -0
  59. data/test/n/ui/tc_pager.rb +3 -3
  60. metadata +41 -65
  61. data/examples/ndb/README +0 -5
  62. data/examples/ndb/run.rb +0 -271
  63. data/lib/n/app/webrick.rb +0 -73
  64. data/lib/n/db.rb +0 -233
  65. data/lib/n/db/README +0 -232
  66. data/lib/n/db/connection.rb +0 -365
  67. data/lib/n/db/managed.rb +0 -233
  68. data/lib/n/db/mixins.rb +0 -279
  69. data/lib/n/db/mysql.rb +0 -345
  70. data/lib/n/db/psql.rb +0 -383
  71. data/lib/n/db/tools.rb +0 -106
  72. data/lib/n/db/utils.rb +0 -102
  73. data/lib/n/server/PLAYBACK.txt +0 -8
  74. data/lib/n/server/RESEARCH.txt +0 -13
  75. data/test/n/tc_db.rb +0 -223
  76. data/test/n/tc_db_mysql.rb +0 -241
@@ -8,7 +8,7 @@
8
8
  # * George Moschovitis <gm@navel.gr>
9
9
  #
10
10
  # (c) 2004 Navel, all rights reserved.
11
- # $Id: config.rb 106 2004-10-25 11:31:11Z gmosx $
11
+ # $Id: config.rb 112 2004-10-27 10:59:55Z gmosx $
12
12
 
13
13
  require "n/logger"
14
14
  require "n/config"
@@ -27,13 +27,13 @@ require "tiny/conf/requires"
27
27
 
28
28
  $srv_extension_map = {
29
29
  "sx" => ["text/html",
30
- N::App::PageHandler.new
30
+ N::PageHandler.new
31
31
  ],
32
32
  "si" => ["text/html",
33
- N::App::PageHandler.new
33
+ N::PageHandler.new
34
34
  ],
35
35
  "rx" => ["text/html",
36
- N::App::CodeHandler.new
36
+ N::CodeHandler.new
37
37
  ]
38
38
  }
39
39
 
@@ -8,12 +8,11 @@
8
8
  # * George Moschovitis <gm@navel.gr>
9
9
  #
10
10
  # (c) 2004 Navel, all rights reserved.
11
- # $Id: requires.rb 101 2004-10-22 12:35:39Z gmosx $
11
+ # $Id: requires.rb 124 2004-11-01 12:34:17Z gmosx $
12
12
 
13
13
  require "n/std"
14
14
  require "n/properties"
15
15
 
16
- require "n/db"
17
16
  require "n/l10n"
18
17
  require "n/logger"
19
18
  require "n/parts"
@@ -29,6 +28,6 @@ require "n/utils/html"
29
28
  require "n/utils/hash"
30
29
  require "n/utils/array"
31
30
 
32
- require "n/app/handlers/page-handler"
33
- require "n/app/handlers/code-handler"
31
+ require "n/server/handlers/page-handler"
32
+ require "n/server/handlers/code-handler"
34
33
 
data/lib/n/config.rb CHANGED
@@ -6,13 +6,13 @@
6
6
  # * George Moschovitis <gm@navel.gr>
7
7
  #
8
8
  # (c) 2004 Navel, all rights reserved.
9
- # $Id: config.rb 106 2004-10-25 11:31:11Z gmosx $
9
+ # $Id: config.rb 116 2004-10-29 16:26:32Z gmosx $
10
10
 
11
11
  # the name of the server
12
12
  $srv_name = "Nitro"
13
13
 
14
14
  # the version of the server
15
- $srv_version = "0.2.0"
15
+ $srv_version = "0.3.0"
16
16
 
17
17
  # monitor scripts for changes
18
18
  #--
@@ -39,4 +39,51 @@ $drb_state = false
39
39
  $error_page_url = nil
40
40
 
41
41
  # default encoding for the app.
42
- $conf_encoding = "iso-8859-1"
42
+ $encoding = "iso-8859-1"
43
+
44
+ if $DBG
45
+
46
+ puts "\nRunning DEBUG configuration.\n\n"
47
+
48
+ # Logger (redirect to STDERR)
49
+
50
+ $log = Logger.new(STDERR);
51
+ $log.level = Logger::DEBUG
52
+
53
+ # If set to true disables xsl caching. Usefull when debugging xsls.
54
+
55
+ $reload_xsl = true
56
+
57
+ # If set to true disables script compilation. Usefull when debugging
58
+ # statically included scripts.
59
+
60
+ $reload_scripts = true
61
+
62
+ # Standard server setup for debugging.
63
+
64
+ $srv_address = $appsrv_address = "127.0.0.1"
65
+ $srv_port = 8080
66
+ $appsrv_port = 9090
67
+ $srv_url = "http://#$srv_address:#$srv_port"
68
+
69
+ else
70
+
71
+ puts "\nRunning LIVE configuration.\n\n"
72
+
73
+ # If set to true disables xsl caching. Usefull when debugging xsls.
74
+
75
+ $reload_xsl = false
76
+
77
+ # If set to true disables script compilation. Usefull when debugging
78
+ # statically included scripts.
79
+
80
+ $reload_scripts = false
81
+
82
+ # Standard server setup for live server. You probably
83
+ # want to override this.
84
+
85
+ $srv_address = $appsrv_address = "127.0.0.1"
86
+ $srv_port = 8080
87
+ $appsrv_port = 9090
88
+ $srv_url = "http://#$srv_address:#$srv_port"
89
+ end
data/lib/n/logger.rb CHANGED
@@ -4,10 +4,10 @@
4
4
  # purposes.
5
5
  #
6
6
  # code:
7
- # George Moschovitis <gm@navel.gr>
7
+ # * George Moschovitis <gm@navel.gr>
8
8
  #
9
9
  # (c) 2004 Navel, all rights reserved.
10
- # $Id: logger.rb 98 2004-10-22 07:36:20Z gmosx $
10
+ # $Id: logger.rb 109 2004-10-27 09:12:45Z gmosx $
11
11
 
12
12
  require "logger"
13
13
 
@@ -35,5 +35,17 @@ class Logger
35
35
  def i(obj)
36
36
  self << "Inspect #{obj.inspect()}\n"
37
37
  end
38
+
39
+ private
40
+
41
+ # the default Ruby logger has a hardwired silly format.
42
+ # we use some Ruby magic to fix it!
43
+ remove_const "Format"
44
+
45
+ Format = "%c: %s\n"
46
+
47
+ def format_message(severity, timestamp, msg, progname)
48
+ Format % [severity[0], msg]
49
+ end
38
50
  end
39
51
 
data/lib/n/og.rb ADDED
@@ -0,0 +1,381 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ #
4
+ # (c) 2004 Navel, all rights reserved.
5
+ # $Id: og.rb 124 2004-11-01 12:34:17Z gmosx $
6
+
7
+ require "n/properties"
8
+ require "n/utils/array"
9
+ require "n/utils/hash"
10
+ require "n/utils/time"
11
+ require "n/utils/pool"
12
+
13
+ require "n/og/meta"
14
+
15
+ module N
16
+
17
+ # If true, only allow reading from the database. Usefull
18
+ # for maintainance.
19
+ #
20
+ $og_read_only_mode = false
21
+
22
+ # If true, the library automatically 'enchants' managed classes.
23
+ # In enchant mode, special db aware methods are added to
24
+ # managed classes and instances.
25
+ #
26
+ $og_enchant_managed_classes = true
27
+
28
+ # = Og
29
+ #
30
+ # Og (ObjectGraph) is an efficient, yet simple Object-Relational
31
+ # mapping library.
32
+ #
33
+ # == Features
34
+ #
35
+ # The library provides the following features:
36
+ #
37
+ # + Object-Relational mapping.
38
+ # + Absolutely no configuration files.
39
+ # + Multiple backends (PostgreSQL, MySQL).
40
+ # + ActiveRecord-style meta language and db aware methods.
41
+ # + Deserialize to Ruby Objects or ResultSets.
42
+ # + Deserialize sql join queries to Ruby Objects.
43
+ # + Serialize arbitrary ruby object graphs through YAML.
44
+ # + Connection pooling.
45
+ # + Thread safety.
46
+ # + SQL transactions.
47
+ # + Lifecycle callbacks.
48
+ # + Transparent support for cascading deletes for all backends.
49
+ # + Hierarchical structures (preorder traversal, materialized paths)
50
+ # + Works safely as part of distributed application.
51
+ # + Simple implementation < 2k lines of code.
52
+ #
53
+ # === Meta language
54
+ #
55
+ # primary_key :pid
56
+ # prop_accessor Fixnum, :pid, :sql => "smallint DEFAULT 1"
57
+ # has_many Child, :children
58
+ # many_to_many Role, :roles
59
+ # sql_index :pid
60
+ #
61
+ # === Design
62
+ #
63
+ # Keep the main classes backend agnostic.
64
+ #
65
+ # Try to make the methods work with oids. Do NOT implement descendants
66
+ # use a root id (rid).
67
+ #
68
+ # For class ids we use the name instead of a hash. Class ids are
69
+ # typically not used in querys, they are stored for completeness.
70
+ # If we store a hash we cannot reclaim the class thus invalidating
71
+ # the point. Instead of .name(), to_s() is used so the methods
72
+ # are more flexible (they accept class names too!!)
73
+ #
74
+ # Og allows the serialization of arbitrary Ruby objects. Just
75
+ # mark them as Object (or Array or Hash) in the prop_accessor
76
+ # and the engine will serialize a YAML dump of the object.
77
+ # Arbitrary object graphs are supported too.
78
+ #
79
+ # This is NOT a singleton, an application may access multiple
80
+ # databases.
81
+ #
82
+ # The $og.xxx methods are more flexible and allow you to use
83
+ # multiple databases for example.
84
+ #
85
+ # === Managed Objects Lifecycle Callbacks
86
+ #
87
+ # * og_pre_insert
88
+ # * og_post_insert
89
+ # * og_pre_update
90
+ # * og_post_update
91
+ # * og_pre_insert_update
92
+ # * og_post_insert_update
93
+ # * self.og_pre_delete
94
+ # * validate
95
+ #
96
+ # A class level callback is used for delete because typically you call
97
+ # delete with an oid and not an object to avoid a deserialization.
98
+ #
99
+ # === Future
100
+ #
101
+ # * Support prepared statements (pgsql)
102
+ # * Support stored procedures (pgsql)
103
+ # * Support caching.
104
+ # * Deserialize to OpenStruct.
105
+ # * Better documentation.
106
+ #
107
+ class Og
108
+
109
+ # Managed class metadata
110
+ #
111
+ class ManagedClassMeta
112
+ # The managed class.
113
+ attr_accessor :klass
114
+
115
+ # A mapping of the database fields to the object properties.
116
+ attr_accessor :field_index
117
+
118
+ def initialize(klass = nil)
119
+ @klass = klass
120
+ @field_index = {}
121
+ end
122
+ end
123
+
124
+ # hash of configuration options.
125
+ attr_accessor :config
126
+
127
+ # Pool of connections to the backend.
128
+ attr_accessor :connection_pool
129
+
130
+ # Managed classes.
131
+ attr_accessor :managed_classes
132
+
133
+ # Initialize the database interface.
134
+ #
135
+ def initialize(config)
136
+ @config = config
137
+
138
+ # populate with default options if needed.
139
+ @config[:connection_count] ||= 1
140
+
141
+ # require the backend.
142
+ backend = @config[:backend] || "psql"
143
+ require "n/og/backends/#{backend}"
144
+ eval %{ @config[:backend] = #{backend.capitalize}Backend }
145
+
146
+ @connection_pool = N::Pool.new
147
+ @managed_classes = N::SafeHash.new
148
+
149
+ $log.info "Connecting to database '#{@config[:database]}' using backend '#{backend}'."
150
+
151
+ @config[:connection_count].times do
152
+ @connection_pool << N::OgConnection.new(self)
153
+ end
154
+ end
155
+
156
+ # Shutdown the database interface.
157
+ #
158
+ def shutdown
159
+ for con in @connection_pool
160
+ con.close()
161
+ end
162
+ end
163
+ alias_method :close, :shutdown
164
+
165
+ # Get a connection from the pool to access the database.
166
+ # Stores the connection in a thread-local variable.
167
+ #
168
+ def get_connection
169
+ $log.debug "Get Og connection" if $DBG
170
+
171
+ thread = Thread.current
172
+
173
+ unless conn = thread[:og_conn]
174
+ conn = @connection_pool.pop()
175
+ thread[:og_conn] = conn
176
+ end
177
+
178
+ return conn
179
+ end
180
+
181
+ # Restore an unused connection to the pool.
182
+ #
183
+ def put_connection
184
+ $log.debug "Put Og connection" if $DBG
185
+
186
+ thread = Thread.current
187
+
188
+ if conn = thread[:og_conn]
189
+ thread[:og_conn] = nil
190
+ return @connection_pool.push(conn)
191
+ end
192
+ end
193
+
194
+ # Utility method, automatically restores a connection to the pool.
195
+ #
196
+ def connect(deserialize = nil, &block)
197
+ result = nil
198
+
199
+ begin
200
+ conn = get_connection()
201
+ conn.deserialize = deserialize unless deserialize.nil?
202
+
203
+ result = yield(conn)
204
+
205
+ conn.deserialize = true
206
+ ensure
207
+ put_connection()
208
+ end
209
+
210
+ return result
211
+ end
212
+ alias_method :open, :connect
213
+
214
+
215
+ # Register a standard Ruby class as managed.
216
+ #
217
+ def manage(klass)
218
+ return if managed?(klass)
219
+
220
+ @managed_classes[klass] = ManagedClassMeta.new(klass)
221
+
222
+ # Add standard og methods to the class.
223
+ convert(klass)
224
+
225
+ # Add helper methods to the class.
226
+ enchant(klass) if $og_enchant_managed_classes
227
+ end
228
+
229
+ # Helper method to set multiple managed classes.
230
+ #
231
+ def manage_classes(*klasses)
232
+ for klass in klasses
233
+ manage(klass)
234
+ end
235
+ end
236
+
237
+ # Stop managing a Ruby class
238
+ #
239
+ def unmanage(klass)
240
+ @managed_classes.delete(klass)
241
+ end
242
+
243
+ # Is this class managed?
244
+ #
245
+ def managed?(klass)
246
+ return @managed_classes.include?(klass)
247
+ end
248
+
249
+ # Add standard og functionality to the class
250
+ #
251
+ def convert(klass)
252
+ # gmosx: this check is needed to allow the developer to customize
253
+ # the sql generated for oid
254
+ N::OgUtils.eval_og_oid(klass) unless klass.instance_methods.include?(:oid)
255
+
256
+ klass.class_eval %{
257
+ inherit_meta(superclass) if superclass
258
+
259
+ DBTABLE = "#{N::OgUtils.table(klass)}"
260
+ DBSEQ = "#{N::OgUtils.table(klass)}_oids_seq"
261
+
262
+ def to_i()
263
+ @oid
264
+ end
265
+ }
266
+
267
+ # Create the schema for this class if not available.
268
+ create_table(klass)
269
+
270
+ # Precompile some code that gets executed all the time.
271
+ # Deletion code is not precompiled, because it is not used
272
+ # as frequently.
273
+ N::OgUtils.eval_og_insert(klass)
274
+ N::OgUtils.eval_og_update(klass)
275
+ N::OgUtils.eval_og_deserialize(klass, self)
276
+ end
277
+
278
+ # Enchant a managed class. Add useful DB related methods to the
279
+ # class and its instances.
280
+ #
281
+ def enchant(klass)
282
+ klass.class_eval %{
283
+ def self.save(obj)
284
+ $og << obj
285
+ end
286
+
287
+ def self.load(oid_or_name)
288
+ $og.load(oid_or_name, #{klass})
289
+ end
290
+
291
+ def self.[](oid_or_name)
292
+ $og.load(oid_or_name, #{klass})
293
+ end
294
+
295
+ def self.load_all(extra_sql = nil)
296
+ $og.load_all(#{klass}, extra_sql)
297
+ end
298
+
299
+ def self.all(extra_sql = nil)
300
+ $og.load_all(#{klass}, extra_sql)
301
+ end
302
+
303
+ def self.select(sql)
304
+ $og.select(sql, #{klass})
305
+ end
306
+
307
+ def self.select_one(sql)
308
+ $og.select_one(sql, #{klass})
309
+ end
310
+
311
+ def self.delete(obj_or_oid)
312
+ $og.delete(obj_or_oid, #{klass})
313
+ end
314
+
315
+ def save
316
+ $og << self
317
+ end
318
+ alias_method :save!, :save
319
+
320
+ def update_properties(updatesql)
321
+ $og.pupdate(updatesql, self.oid, #{klass})
322
+ end
323
+ alias_method :pupdate!, :update_properties
324
+
325
+ def delete!
326
+ $og.delete(@oid, #{klass})
327
+ end
328
+ }
329
+ end
330
+
331
+ # Automatically wrap connection methods.
332
+ #
333
+ def self.wrap_method(method, args)
334
+ args = args.split(/,/)
335
+ class_eval %{
336
+ def #{method}(#{args.join(", ")})
337
+ thread = Thread.current
338
+
339
+ unless conn = thread[:og_conn]
340
+ conn = @connection_pool.pop()
341
+ thread[:og_conn] = conn
342
+ end
343
+
344
+ return conn.#{method}(#{args.collect {|a| a.split(/=/)[0]}.join(", ")})
345
+ end
346
+ }
347
+ end
348
+
349
+ wrap_method :create_table, "klass"
350
+ wrap_method :drop_table, "klass"
351
+ wrap_method :save, "obj"; alias_method :<<, :save; alias_method :put, :save
352
+ wrap_method :insert, "obj"
353
+ wrap_method :update, "obj"
354
+ wrap_method :update_properties, "update_sql, obj_or_oid, klass = nil"
355
+ wrap_method :pupdate, "update_sql, obj_or_oid, klass = nil"
356
+ wrap_method :load, "oid, klass"; alias_method :get, :load
357
+ wrap_method :load_by_oid, "oid, klass"
358
+ wrap_method :load_by_name, "name, klass"
359
+ wrap_method :load_all, "klass, extrasql = nil"
360
+ wrap_method :select, "sql, klass"
361
+ wrap_method :select_one, "sql, klass"
362
+ wrap_method :delete, "obj_or_oid, klass = nil"
363
+ wrap_method :query, "sql"
364
+ wrap_method :exec, "sql"
365
+
366
+ def self.create_db!(config)
367
+ get_connection().db.create_db(config[:database], config[:user],
368
+ config[:password])
369
+ end
370
+
371
+ def self.drop_db!(config)
372
+ backend = config[:backend] || "psql"
373
+ require "n/og/backends/#{backend}"
374
+ eval %{
375
+ #{backend.capitalize}Backend.drop_db(config[:database], config[:user],
376
+ config[:password])
377
+ }
378
+ end
379
+ end
380
+
381
+ end # module