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
data/lib/n/db/managed.rb DELETED
@@ -1,233 +0,0 @@
1
- # code:
2
- # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
5
- # $Id: managed.rb 99 2004-10-22 09:50:28Z gmosx $
6
-
7
-
8
- # Extend the base Module class
9
- #
10
- # Implements the meta-language used to create/fine-tune
11
- # the generated sql.
12
- #
13
- class Module
14
-
15
- # Create an sql index. Wrapper arrount meta :sql_index.
16
- # This creates ONE sql index.
17
- # The input parameter is a String (for many symbols) or
18
- # a Symvol
19
- #
20
- def sql_index(symbols, pre_sql = nil, post_sql = nil)
21
- # gmosx, TODO: meta[:sql_index] should store the full sql clause
22
- # to allow for custom indices (for example partial indices,
23
- # hash indices and more)
24
- meta(:sql_index, [symbols.to_s, pre_sql, post_sql])
25
- end
26
-
27
- # Wrap prop/meta declarations.
28
- #
29
- def manage(&block)
30
- inherit_meta(superclass) if superclass
31
-
32
- yield
33
-
34
- N::Managed.eval_dbseq(self)
35
- N::Managed.eval_dbtable(self)
36
- # gmosx: this is called from DbConnection
37
- # N::Managed.eval_db_read_row(self)
38
- N::Managed.eval_db_insert(self)
39
- N::Managed.eval_db_update(self)
40
- end
41
-
42
- end
43
-
44
- module N;
45
-
46
- require "n/properties"
47
- require "n/utils/array"
48
- require "n/utils/time"
49
-
50
- # = Managed
51
- #
52
- # Base Mixin for Managed Objects (Entities)
53
- #
54
- # The database interfaces automatically manages classes that
55
- # include this interface.
56
- #
57
- module Managed
58
- # Use this hash to store sql join query fields.
59
- # DONT create this hash unless needed!
60
- attr_accessor :join_fields
61
-
62
- #
63
- #
64
- def initialize(*args)
65
- end
66
-
67
- # A list of potential ancestor classes
68
- # Returns an array of classes.
69
- #
70
- def __ancestors_classes
71
- return nil
72
- end
73
-
74
- # A list of potential descendants classes
75
- # Typically used in cascading deletes.
76
- # Returns an array of classes.
77
- #
78
- def __descendants_classes
79
- return nil
80
- end
81
-
82
- # --------------------------------------------------------------------
83
- # DB Hooks
84
-
85
- # Define the primary key as a string.
86
- #
87
- def __db_pk
88
- return nil
89
- end
90
-
91
- # Add code to be executed before the managed object is inserted.
92
- # Typically creates the primary key.
93
- #
94
- def __db_pre_insert(conn)
95
- # nop
96
- end
97
-
98
- # Add code to be executed before the managed object is deleted.
99
- # Typically used for cascading deletes, executed in a transaction,
100
- # do NOT error-check here!
101
- #
102
- def __db_pre_delete(conn)
103
- # nop
104
- end
105
-
106
- # This method is called to deserialize a resultset from the
107
- # database. This definition is ovveriden by the evaluated code from
108
- # eval_db_read_row.
109
- #
110
- def __db_insert(conn)
111
- # nop
112
- end
113
-
114
- # This method is called to insert a managed object in the database.
115
- # This definition is ovveriden by the evaluated code from
116
- # eval_db_update.
117
- #
118
- def __db_insert(conn)
119
- # nop
120
- end
121
-
122
- # This method is called to update a managed object in the database.
123
- # This definition is ovveriden by the evaluated code from
124
- # eval_db_update.
125
- #
126
- def __db_update(conn)
127
- raise "No primary key defined, cannot update"
128
- end
129
-
130
- # --------------------------------------------------------------------
131
-
132
- # Evaluate the DBSEQ constant for the given class.
133
- # Classes that include the N::Sequenced marker have
134
- # a custom sequence.
135
- #
136
- # INVESTIGATE: how to implement this for MySQL?
137
- #
138
- def self.eval_dbseq(klass)
139
- if klass.include?(N::Sequenced)
140
- klass.module_eval %{
141
- DBSEQ = "#{N::DbUtils.sql_table(klass)}_oids_seq"
142
- }
143
- else
144
- klass.module_eval %{
145
- DBSEQ = "oids_seq"
146
- }
147
- end
148
- end
149
-
150
- # Evaluate the DBTABLE constant for the given class.
151
- #
152
- def self.eval_dbtable(klass)
153
- klass.module_eval %{
154
- DBTABLE = "#{N::DbUtils.sql_table(klass)}"
155
- }
156
- end
157
-
158
- # Precompile the code to read objects of the given class
159
- # from the backend.
160
- #
161
- # In order to allow for changing field/attribute orders we
162
- # have to use a field mapping hash.
163
- #
164
- def self.eval_db_read_row(klass)
165
- props = klass.__props
166
- code = []
167
-
168
- props.each { |p|
169
- if idx = $db.fields[klass][p.name]
170
- # more fault tolerant if a new field is added and it
171
- # doesnt exist in the database.
172
- code << "@#{p.name} = #{N::DbUtils.read_prop(p, idx)}"
173
- end
174
- }
175
- klass.module_eval %{
176
- def __db_read_row(rows, tuple)
177
- #{code.join('; ')}
178
- end
179
- }
180
- end
181
-
182
- # Precompile the insert code for the given class.
183
- #
184
- # gmosx: SET the oid when inserting!
185
- #
186
- def self.eval_db_insert(klass)
187
- props = klass.__props
188
-
189
- values = props.collect { |p|
190
- N::DbUtils.write_prop(p)
191
- }
192
-
193
- sql = "INSERT INTO #{N::DbUtils.sql_table(klass)} (#{props.collect {|p| p.name}.join(',')}) VALUES (#{values.join(',')})"
194
-
195
- klass.module_eval %{
196
- def __db_insert(conn)
197
- __db_pre_insert(conn)
198
- conn.retry_query("#{sql}", #{klass})
199
- end
200
- }
201
- end
202
-
203
- # Precompile the update code for the given class.
204
- #
205
- # gmosx: ignore the oid when updating!
206
- #
207
- def self.eval_db_update(klass)
208
- props = klass.__props.reject { |p| :oid == p.symbol }
209
-
210
- updates = props.collect { |p|
211
- "#{p.name}=#{N::DbUtils.write_prop(p)}"
212
- }
213
-
214
- # the primary key
215
-
216
- if pk = klass.new.__db_pk
217
- # only evaluate the update code if the object
218
- # defines a primary key.
219
-
220
- sql = "UPDATE #{klass::DBTABLE} SET #{updates.join(', ')} WHERE #{pk}=#\{@#{pk}\}"
221
-
222
- klass.module_eval %{
223
- def __db_update(conn)
224
- conn.retry_query("#{sql}", #{klass})
225
- end
226
- }
227
- end
228
- end
229
-
230
- end
231
-
232
- end # module
233
-
data/lib/n/db/mixins.rb DELETED
@@ -1,279 +0,0 @@
1
- # = Database Managed Mixins
2
- #
3
- # Useful mixins for synthesizing managed objects. All mixins should
4
- # have at least initialize(*args) to be more chainable?
5
- #
6
- # code:
7
- # * George Moschovitis <gm@navel.gr>
8
- #
9
- # (c) 2004 Navel, all rights reserved.
10
- # $Id: mixins.rb 99 2004-10-22 09:50:28Z gmosx $
11
-
12
- module N;
13
-
14
- # = Entity
15
- #
16
- # The default managed Object. Include this mixin to the
17
- # objects to be managed by Db.
18
- #
19
- module Entity
20
- include Managed
21
-
22
- # The unique object id. PRIMARY KEY automatically creates an index.
23
- prop_accessor Fixnum, "integer PRIMARY KEY", :oid
24
-
25
- def initialize(*args)
26
- super
27
- end
28
-
29
- #
30
- #
31
- def __db_pk
32
- return "oid"
33
- end
34
-
35
- # Default implementation, calculates the oid primary key.
36
- #
37
- def __db_pre_insert(conn)
38
- # gmosx, INVESTIGATE: is this neeed?
39
- super
40
- @oid = conn.next_oid(self.class)
41
- end
42
-
43
- # Default implementation, cascading delete.
44
- # Typically used for cascading deletes, executed in a transaction,
45
- # do NOT error-check here!
46
- #
47
- def __db_pre_delete(conn)
48
- conn.delete_descendants(@oid, self.class)
49
- end
50
-
51
- def to_i()
52
- return @oid
53
- end
54
- end
55
-
56
- # An entity that uses a custom sequence.
57
- # This is a marker mixin. Entities tha include this mixin
58
- # do not participated in the unified id space
59
- #
60
- module Sequenced;
61
- def initialize(*args)
62
- super
63
- end
64
- end
65
-
66
- #
67
- #
68
- module CreateTime
69
- prop_accessor Time, :create_time
70
-
71
- def initialize(*args)
72
- super
73
- @create_time = Time.now()
74
- end
75
-
76
- end
77
-
78
- # = Relation
79
- #
80
- # Relations between entities.
81
- #
82
- # gmosx: The oid is need in relations too, as a primary key.
83
- # Another pk could be (pid, pclass, tid, tclass) but this is too
84
- # big.
85
- #
86
- module Relation
87
- include Entity
88
- include CreateTime
89
- include Sequenced
90
-
91
- # The parent id.
92
- prop_accessor Fixnum, "integer NOT NULL", :pid
93
-
94
- # The parent class
95
- prop_accessor String, :pclass
96
-
97
- # The target oid
98
- prop_accessor Fixnum, "integer NOT NULL", :tid
99
-
100
- # The target class
101
- prop_accessor String, :tclass
102
-
103
- # combined index (tid, tclass)
104
- sql_index "tid, tclass"
105
-
106
- def set_parent(parent, klass = nil)
107
- if parent.is_a?(Fixnum)
108
- @pid = parent
109
- @pclass = klass.to_s if klass
110
- else
111
- @pid = parent.oid
112
- @pclass = parent.class.to_s()
113
- end
114
- end
115
-
116
- def set_target(target, klass = nil)
117
- if target.is_a?(Fixnum)
118
- @tid = target
119
- @tclass = klass.to_s if klass
120
- else
121
- @tid = target.oid
122
- @tclass = target.class.to_s()
123
- end
124
- end
125
-
126
- end
127
-
128
- # = RelationUtils
129
- #
130
- # A collection of general Relation utilities. Extend this method in your
131
- # classes.
132
- #
133
- module RelationUtils
134
-
135
- # Return the targets for the given parent.
136
- #
137
- def targets_for_parent(pid, pclass, tclass, extrasql = nil)
138
- return $db.select("SELECT f.*, r.oid AS relid, r.create_time AS relct FROM #{tclass::DBTABLE} AS f, #{self::DBTABLE} AS r WHERE f.oid=r.tid #{extrasql}", tclass, [:relid, :relct])
139
- end
140
-
141
- # Count targets for the given parent
142
- #
143
- def count_targets_for_parent(pid, pclass, tclass, extrasql = nil)
144
- return $db.count("SELECT COUNT(*) FROM #{tclass::DBTABLE} AS f, #{self::DBTABLE} AS r WHERE f.oid=r.tid #{extrasql}")
145
- end
146
-
147
- end
148
-
149
- # = Named
150
- #
151
- # Include this mixin to make an entity named. The Db interface
152
- # provides special lookup methods for Named entities.
153
- #
154
- module Named
155
- # The object name, used in named lookups.
156
- prop_accessor String, :name; sql_index :name
157
- end
158
-
159
- # = Child
160
- #
161
- # Include this mixin to make and entity attachable to a parent
162
- # Entity.
163
- #
164
- module Child
165
- # The parent oid
166
- prop_accessor Fixnum, "integer NOT NULL", :pid
167
-
168
- # DONT use combined index (pid, pclass), this is seldom used in
169
- # queries, use only the pid as index!
170
- sql_index :pid
171
-
172
- def initialize(*args)
173
- super
174
- end
175
-
176
- def set_parent(parent)
177
- @pid = parent.to_i
178
- end
179
- end
180
-
181
- # = ParentClass
182
- #
183
- # Extends Child, allows multiple class parents.
184
- #
185
- module ParentClass
186
-
187
- # The parent class
188
- #
189
- # This is usually not used in queries, we add it so the database
190
- # is 'complete'
191
- # pclass stores the class name and NOT the actual class.
192
- # this optimizes most of the code, and allows to pass the pclass
193
- # parameter through standard URIs.
194
- #
195
- # Originally it stored the class hash but then we couldnt lookup
196
- # the actual class (hashes are oneway transforms).
197
- #
198
- prop_accessor String, :pclass
199
-
200
- def set_parent(parent, klass = nil)
201
- if parent.is_a?(Fixnum)
202
- @pid = parent
203
- @pclass = klass.to_s() if klass
204
- else
205
- @pid = parent.oid
206
- @pclass = parent.class.to_s()
207
- end
208
- end
209
-
210
- end
211
-
212
- # = SqlTreeTraversable
213
- #
214
- # Implements the common Preorder Tree Traversal SQL pattern.
215
- # Usefull if you need to combine a Hierarchical view with
216
- # an SQL LIMIT clause.
217
- #
218
- # The technique is further discussed here:
219
- # http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html
220
- #
221
- # depth is used in the limit scenarios.
222
- # This pattern works well with stored procedures.
223
- #
224
- # initialy depth = 0, lft = 0, rgt = 1
225
- #
226
- # Optimization: instead of lft,rgt it only stores tree_index, so it cannot
227
- # generate subtrees.
228
- #
229
- module SqlTreeTraversable
230
- # SQL reserves left, right
231
- prop_accessor Fixnum, "smallint", :lft, :rgt
232
- prop_accessor Fixnum, "smallint", :depth
233
-
234
- # If depth, lft, rgt are not initialized try to autocalculate
235
- # from the parent.
236
- #
237
- def __db_pre_insert(conn)
238
- super
239
- unless @depth
240
- @depth = 0
241
- @lft = 0
242
- @rgt = 1
243
- end
244
- end
245
-
246
- def insert_into_sql_tree(prgt, pdepth)
247
- @depth = pdepth.to_i() + 1
248
- @lft = prgt.to_i()
249
- @rgt = @lft + 1
250
- end
251
-
252
- end
253
-
254
- # = ManagedChild
255
- #
256
- # A common type of non-entity
257
- #
258
- module ManagedChild
259
- include N::Managed
260
-
261
- # The parent oid
262
- prop_accessor Fixnum, "integer PRIMARY KEY", :pid
263
-
264
- def initialize(parent = nil)
265
- @pid = parent.to_i
266
- end
267
-
268
- def set_parent(parent)
269
- @pid = parent.to_i
270
- end
271
-
272
- # pid is the primary key
273
- def __db_pk
274
- return "pid"
275
- end
276
- end
277
-
278
- end # module
279
-