nitro 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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