nitro 0.1.2

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