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
data/lib/n/db/README DELETED
@@ -1,232 +0,0 @@
1
- = n/db README
2
-
3
- == Table of Contents
4
-
5
- 1. Introduction
6
- 2. Features
7
- 3. Sample Code
8
- 4. Technical Information
9
- 5. Links
10
- 6. Current Version and Status
11
- 7. Feedback
12
- 8. Licence
13
-
14
-
15
- == Introduction
16
-
17
- The aim of this project is to deliver an efficient, yet simple,
18
- Object-Relational Mapper Library. The library manages the
19
- lifecycle of standard Ruby objects. Unlike similar projects, our
20
- approach requires neither xml configuration files (i.e. J2EE), nor
21
- SQL definitions (i.e. ActiveRecord).
22
-
23
- By defining the Managed Objects (or Entities) using Ruby, we
24
- leverage Ruby's OOP features to allow for OO definitions of DataBase
25
- schemas. A simple meta-language is provided to allow fine-tuning
26
- of the generated SQL code.
27
-
28
- This library is designed to be integrated in a Web Application
29
- Framework. This Framework will be released on a later day.
30
-
31
-
32
- == Features
33
-
34
- The library provides the following features:
35
-
36
- + Object-Relational mapping
37
- + Deserialize to Ruby Objects or ResultSets
38
- + Deserialize sql join queries to Ruby Objects
39
- + Serialize arbitrary ruby object graphs through Marshal
40
- + Connection pooling
41
- + Thread safety
42
- + SQL transactions
43
- + Callbacks
44
- + Simple support for cascading deletes
45
- + Hierarchical structures (preorder traversal, materialized paths)
46
- + Works safely as part of distributed application.
47
- + Simple implementation < 10k lines of code.
48
-
49
- == Sample Code
50
-
51
- require "n/db"
52
-
53
- # initialize the DB interface
54
- $db = N::Db.new(
55
- :address => "localhost",
56
- :database => "test",
57
- :user => "postgres",
58
- :password => "mypassword",
59
- :connection_count => 20
60
- )
61
-
62
- # create a managed object
63
-
64
- class MyObject
65
- include N::Entity
66
- manage {
67
- prop String, :name
68
- prop [Fixnum, "smallint default 1"], :level; sql_index :level
69
- }
70
- # non serialized attributes
71
- attr_accessor value
72
- end
73
-
74
- class AnotherObject < MyObject
75
- manage {
76
- prop Time, :create_time
77
- }
78
-
79
- def initialize
80
- @create_time = Time.now
81
- super
82
- end
83
- end
84
-
85
- obj = AnotherObject.new
86
- obj.name = "gmosx"
87
-
88
- # insert into db
89
- $db << obj
90
-
91
- obj.name = "drak"
92
-
93
- # update
94
- $db << obj
95
-
96
- # get object id allocated when inserting
97
- oid = obj.oid
98
-
99
- # lookup
100
- obj = $db.get(oid, AnotherObject)
101
-
102
- # multiple commands
103
-
104
- $db.open { |db|
105
- obj = db.get(oid, AnotherObject)
106
- db.delete(obj)
107
- db.select("SELECT * FROM #{AnotherObject::DBTABLE} WHERE oid=1")
108
- }
109
-
110
- # graph like objects
111
-
112
- class Child
113
- include N::Entity
114
- include N::Child
115
- manage {
116
- prop Time, :create_time
117
- }
118
- end
119
-
120
- child = Child.new
121
- child.set_parent(obj)
122
-
123
- $db << child
124
-
125
- # get children of class Child
126
-
127
- $db.children(obj, Child, "ORDER BY create_time")
128
-
129
- # sql transactions
130
-
131
- $db.transaction {
132
- ...
133
- }
134
-
135
- # Lets say you have changed the definition of a managed object
136
- # (for example you have added a new prop_accessor, and want to
137
- # automatically update the database schema:
138
- #
139
-
140
- $db.alter_table(MyObject)
141
-
142
-
143
- == Technical Information
144
-
145
- === Installation
146
-
147
- Just uncompress the distribution and add the 'n' directory to
148
- the Ruby path.
149
-
150
- tar xvfz ndb-x.x.tar.gz
151
- cd ndb
152
- ruby n/.tc-db.rb
153
-
154
- === How the package is organized:
155
-
156
- n/db.rb:
157
- The main n/db file.
158
-
159
- n/db/*:
160
- The db related files.
161
-
162
- n/utils/*:
163
- Various utility files.
164
-
165
- === Testing:
166
-
167
- Unit Test files start with the .tc- prefix, i.e. they are hidden
168
- by default (Unix). You can run the db test unit as follows:
169
-
170
- ruby n/.tc-db.rb
171
-
172
- Before running this test unit, make sure tha the postgreSQL server
173
- is running, and the 'test' database is created.
174
-
175
-
176
- == Links
177
-
178
- * http://www.navel.gr, Navel
179
- * http://www.navel.gr/open-source, Project Home Page
180
-
181
-
182
- == Current Version and Status
183
-
184
- Version 0.3 was released on 15-10-2004. The source is cleaned up and
185
- the API refined. Added preliminary support for multiple backends (the
186
- included MySQL backend is not completed). Added support for
187
- marshaled fields. Available as a RubyGem too.
188
-
189
- Version 0.2 was released on 07-10-2004. The sofware is actually usable
190
- but not tested in a production environment. Comments from the Ruby
191
- community are critical in order to fix possible bugs and improve the
192
- API. Suggestions for missing features are also welcome. This version
193
- only supports the Postgres Database.
194
-
195
- === Contributors
196
-
197
- * George Moschovitis <gm@navel.gr>: design, lead developer.
198
-
199
- === Future
200
-
201
- * Support multiple DataBase backends (Postgres, MySQL, ...)
202
- * Support prepared statements (pgsql)
203
- * Support stored procedures (pgsql)
204
- * Support caching
205
- * Deserialize to OpenStruct
206
- * Better documentation
207
- * Code cleanup, refactoring
208
- * Release as Gem, RPAbase
209
-
210
-
211
- == Feedback
212
-
213
- If you would like to report a bug, suggest a method for inclusion, or make
214
- some other suggestion (documentation, package layout, etc.), please send
215
- an email to ndb-feedback@navel.gr
216
-
217
-
218
- == Licence
219
-
220
- Copyright (c) 2004 Navel, all rights reserved. http://www.navel.gr
221
-
222
- n/db (http://www.navel.gr/open-source) is copyrighted free software
223
- created and maintained by George Moschovitis (mailto:gm@navel.gr)
224
- and released under the same license as Ruby.
225
-
226
- Standard disclaimer:
227
-
228
- THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
229
- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
230
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
231
- PURPOSE.
232
-
@@ -1,365 +0,0 @@
1
- # code:
2
- # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
5
- # $Id: connection.rb 99 2004-10-22 09:50:28Z gmosx $
6
-
7
- module N;
8
-
9
- require "n/properties"
10
- require "n/utils/array"
11
- require "n/utils/time"
12
-
13
- # = DbConnection
14
- #
15
- # A Connection to the Database.
16
- #
17
- # === design
18
- #
19
- # try to make the methods to work with oids.
20
- # do not implement descendants, use a root id (rid).
21
- #
22
- # === todo
23
- #
24
- # - support caching
25
- # - support prepared statements
26
- # - foreign keys (delete cascade)
27
- # - keep attribudes as marshaled!!
28
- #
29
- # === investigate
30
- #
31
- # - should we use retry_query ?
32
- #
33
- class DbConnection
34
- include N::DbUtils
35
-
36
- # the actual connection to the database.
37
- attr_reader :rdb
38
-
39
- # If set to true, the select methods deserialize the rows to
40
- # create entities.
41
- attr_accessor :deserialize
42
-
43
- # Initializate a connection to the database.
44
- #
45
- def initialize(config)
46
- super
47
- @deserialize = true
48
- $log.debug "Created connection."
49
- end
50
-
51
- # Close the connection to the database.
52
- #
53
- def close()
54
- super
55
- $log.debug "Closed connection."
56
- end
57
-
58
- # --------------------------------------------------------------------
59
- # Basic methods
60
-
61
- # Put an entity to the database. Insert if this is a new entity or
62
- # update if this is an existing entity.
63
- #
64
- def put(entity)
65
- if entity.oid
66
- # entity allready inserted, update!
67
- entity.__db_update(self)
68
- else
69
- # this is a new entity, insert!
70
- entity.__db_insert(self)
71
- end
72
- end
73
- alias_method :<<, :put
74
-
75
- # Force insertion of managed object.
76
- # Typically used for NON-entities.
77
- #
78
- def insert(obj)
79
- obj.__db_insert(self)
80
- end
81
-
82
- # Force update of managed object.
83
- # Typically used for relations.
84
- #
85
- def update(obj)
86
- obj.__db_update(self)
87
- end
88
-
89
- # Update only specific fields of the entity
90
- #
91
- # Input:
92
- # sql = the sql code to updated the properties.
93
- #
94
- def update_properties(update_sql, ent_or_oid, klass = nil)
95
- oid = ent_or_oid.to_i()
96
- klass = ent_or_oid.class unless klass
97
-
98
- sql = "UPDATE #{klass::DBTABLE} SET #{update_sql} WHERE oid=#{oid}"
99
- retry_query(sql, klass)
100
- end
101
- alias_method :pupdate, :update_properties
102
-
103
- # Get an entity from the database.
104
- #
105
- # COOL: klass can be the class to fetch or the DBTABLE of the class.
106
- # thanks to duck typing it works correctly!
107
- #
108
- # Input:
109
- # oid = the entity oid, OR the entity name.
110
- #
111
- def get(oid, klass)
112
- if oid.to_i > 0 # a valid Fixnum ?
113
- get_by_oid(oid, klass)
114
- else
115
- get_by_name(oid, klass)
116
- end
117
- end
118
-
119
- # Get an entity by oid.
120
- #
121
- # COOL: klass can be the class to fetch or the DBTABLE of the class.
122
- # thanks to duck typing it works correctly!
123
- #
124
- def get_by_oid(oid, klass)
125
- rows = safe_query("SELECT * FROM #{DbUtils.sql_table(klass)} WHERE oid=#{oid}")
126
- return deserialize_one(rows, klass)
127
- end
128
-
129
- # Get an entity by name.
130
- #
131
- # COOL: klass can be the class to fetch or the DBTABLE of the class.
132
- # thanks to duck typing it works correctly!
133
- #
134
- def get_by_name(name, klass)
135
- rows = safe_query("SELECT * FROM #{DbUtils.sql_table(klass)} WHERE name='#{name}'")
136
- return deserialize_one(rows, klass)
137
- end
138
-
139
- # Get all entities of the given klass.
140
- #
141
- # COOL: klass can be the class to fetch or the DBTABLE of the class.
142
- # thanks to duck typing it works correctly!
143
- #
144
- # Used to be called 'collect' in an earlier version.
145
- #
146
- def get_all(klass, extrasql = nil)
147
- rows = safe_query("SELECT * FROM #{DbUtils.sql_table(klass)} #{extrasql}")
148
- return deserialize_all(rows, klass)
149
- end
150
-
151
- # Delete an entity from the database. Allways perform a deep delete.
152
- #
153
- # DONT use ::DBTABLE (allow classes as table names).
154
- #
155
- # Input:
156
- #
157
- # entity = Entity or oid to delete.
158
- # klass = klass of entity (can be nil if an entity is passed)
159
- #
160
- def delete(entity, klass = nil, cascade = true)
161
- if entity.is_a?(Fixnum)
162
- oid = entity
163
- entity = klass.new
164
- entity.oid = oid
165
- end
166
-
167
- transaction {
168
- entity.__db_pre_delete(self)
169
- exec_clear("DELETE FROM #{DbUtils.sql_table(entity.class)} WHERE oid=#{entity.oid}")
170
- }
171
- end
172
- alias_method :delete!, :delete
173
-
174
- # Recursively delete all descendants of this entity.
175
- # Operates in a transaction.
176
- #
177
- def delete_descendants(pid, pclass)
178
- return unless pclass.respond_to?(:__descendants_classes)
179
-
180
- for dclass in pclass.__descendants_classes
181
- if dclass.include?(N::ParentClass)
182
- rs = exec("SELECT oid FROM #{dclass::DBTABLE} WHERE pid=#{pid} AND pclass='#{pclass}'")
183
- exec_clear("DELETE FROM #{dclass::DBTABLE} where pid=#{pid} AND pclass='#{pclass}'")
184
- else
185
- rs = exec("SELECT oid FROM #{dclass::DBTABLE} WHERE pid=#{pid}")
186
- exec_clear("DELETE FROM #{dclass::DBTABLE} where pid=#{pid}")
187
- end
188
-
189
- for tuple in (0...rs.num_tuples)
190
- delete_descendants(rs.getvalue(tuple, 0), dclass)
191
- end
192
-
193
- rs.clear()
194
- end
195
- end
196
- alias_method :delete_descendants!, :delete_descendants
197
-
198
- # --------------------------------------------------------------------
199
- # Graph methods
200
-
201
- # = child
202
- #
203
- # Return one children of the parent
204
- #
205
- def child(entity, klass, extrasql = nil)
206
- pid = entity.to_i()
207
-
208
- sql = "SELECT * FROM #{klass::DBTABLE}"
209
- sql << " WHERE pid=#{pid}" if pid > 0
210
- sql << " #{extrasql}" if extrasql
211
-
212
- rows = safe_query(sql)
213
-
214
- return deserialize_one(rows, klass)
215
- end
216
-
217
- # = children
218
- #
219
- # entity = entity or oid.
220
- # klass = the class of the children to return.
221
- # extrasql = extra sql for limit/order etc.
222
- #
223
- # === Design:
224
- #
225
- # If the calculated pid is 0 returns all entities
226
- # of the given class. It works like the older collect method.
227
- # This make sense, the root of all objects has an oid = 0.
228
- # INVESTIGATE: is this a security problem?
229
- #
230
- # only_oids is not needed use the limit modifiers instead.
231
- # if you need oids, use specialized sql. You can use the
232
- # extrasql parameter to change the where clause too.
233
- #
234
- def children(entity, klass, extrasql = nil)
235
- pid = entity.to_i()
236
-
237
- sql = "SELECT * FROM #{klass::DBTABLE}"
238
- sql << " WHERE pid=#{pid}" if pid > 0
239
- sql << " #{extrasql}" if extrasql
240
-
241
- rows = safe_query(sql)
242
-
243
- return deserialize_all(rows, klass)
244
- end
245
-
246
- # = count_children
247
- #
248
- # Use extrasql to change the where clause.
249
- #
250
- def count_children(entity, klass, extasql = nil)
251
- pid = entity.to_i()
252
-
253
- sql = "SELECT COUNT(pid) FROM #{klass::DBTABLE}"
254
- sql << " WHERE pid=#{pid}" if pid > 0
255
-
256
- if rows = safe_query(sql)
257
- return rows[0][0].to_i()
258
- end
259
-
260
- return 0
261
- end
262
-
263
- # --------------------------------------------------------------------
264
- # Transaction methods.
265
-
266
- def start
267
- exec_clear("START TRANSACTION")
268
- end
269
-
270
- def commit
271
- exec_clear("COMMIT")
272
- end
273
-
274
- def rollback
275
- exec_clear("ROLLBACK")
276
- end
277
-
278
- # Transaction helper
279
- #
280
- def transaction(&block)
281
- begin
282
- exec_clear("START TRANSACTION")
283
- yield
284
- exec_clear("COMMIT")
285
- rescue => ex
286
- $log.error "DB Error: ERROR IN TRANSACTION"
287
- $log.error "DB Error: #{ex}, #{caller[0]} : #{caller[1]} : #{caller[2]}"
288
- exec_clear("ROLLBACK")
289
- end
290
- end
291
-
292
- # Useful in transactions
293
- #
294
- def exec(sql)
295
- @rdb.exec(sql)
296
- end
297
-
298
- # Useful in transactions
299
- # Exec an sql command and clear the resultset.
300
- #
301
- def exec_and_clear(sql)
302
- rows = @rdb.exec(sql)
303
- rows.clear()
304
- end
305
- alias_method :exec_clear, :exec_and_clear
306
-
307
- # --------------------------------------------------------------------
308
- # Standard SQL methods.
309
-
310
- # Perform a standard SQL query to the database. Deserializes the
311
- # results.
312
- #
313
- def select(sql, klass, join_fields = nil)
314
- rows = safe_query(sql)
315
- return deserialize_all(rows, klass, join_fields)
316
- end
317
-
318
- # Optimized for one result.
319
- #
320
- def select_one(sql, klass, join_fields = nil)
321
- rows = safe_query(sql)
322
- return deserialize_one(rows, klass, join_fields)
323
- end
324
-
325
- # Perform a standard SQL query to the database. Returns the result
326
- # rows.
327
- #
328
- def query(sql)
329
- return safe_query(sql)
330
- end
331
- alias_method :sql, :query
332
-
333
- # Perform a standard SQL query to the database. Used for queries that
334
- # return one row (typically with values) ie COUNT, etc.
335
- #
336
- def query_one(sql)
337
- if rows = safe_query(sql)
338
- return rows[0]
339
- else
340
- return nil
341
- end
342
- end
343
-
344
- # Count the entities returned by the sql statement.
345
- #
346
- def count(sql)
347
- if rows = safe_query(sql)
348
- return rows[0][0].to_i()
349
- end
350
-
351
- return 0
352
- end
353
-
354
- # Match a query, return true if a resultset was found
355
- #
356
- def match(sql)
357
- res = safe_query(sql)
358
- return true if res and (res.num_tuples > 0)
359
- end
360
- alias_method :match?, :match
361
-
362
- end
363
-
364
- end # module
365
-