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.
- data/ChangeLog +186 -0
- data/README +40 -11
- data/RELEASES +10 -1
- data/Rakefile +5 -4
- data/bin/cluster.rb +3 -3
- data/{etc/new-project.rb → bin/new_app.rb} +1 -1
- data/examples/og/README +4 -0
- data/examples/og/run.rb +254 -0
- data/examples/simple/app.rb +3 -3
- data/examples/simple/conf/config.rb +10 -22
- data/examples/simple/conf/debug-config.rb +6 -32
- data/examples/simple/conf/live-config.rb +3 -23
- data/examples/simple/conf/requires.rb +5 -5
- data/examples/simple/env.rb +3 -4
- data/examples/simple/lib/articles/entities.rb +17 -15
- data/examples/simple/lib/articles/methods.rb +15 -15
- data/examples/simple/lib/articles/part.rb +7 -8
- data/examples/simple/root/comments.si +1 -1
- data/examples/simple/root/index.sx +1 -1
- data/examples/simple/root/view-article.sx +1 -2
- data/examples/tiny/app.rb +3 -3
- data/examples/tiny/conf/config.rb +4 -4
- data/examples/tiny/conf/requires.rb +3 -4
- data/lib/n/config.rb +50 -3
- data/lib/n/logger.rb +14 -2
- data/lib/n/og.rb +381 -0
- data/lib/n/og/backend.rb +252 -0
- data/lib/n/og/backends/mysql.rb +352 -0
- data/lib/n/og/backends/psql.rb +351 -0
- data/lib/n/og/connection.rb +253 -0
- data/lib/n/og/meta.rb +127 -0
- data/lib/n/properties.rb +6 -6
- data/lib/n/server.rb +4 -7
- data/lib/n/server/appserver.rb +58 -0
- data/lib/n/{app → server}/cluster.rb +3 -3
- data/lib/n/{app → server}/cookie.rb +3 -3
- data/lib/n/server/dispatcher.rb +55 -0
- data/lib/n/server/{filter.rb → filters.rb} +1 -1
- data/lib/n/{app → server}/filters/autologin.rb +5 -5
- data/lib/n/{app → server}/fragment.rb +3 -3
- data/lib/n/{app → server}/handlers.rb +4 -4
- data/lib/n/{app → server}/handlers/code-handler.rb +6 -6
- data/lib/n/{app → server}/handlers/page-handler.rb +9 -7
- data/lib/n/{app → server}/request.rb +8 -8
- data/lib/n/{app/request-part.rb → server/requestpart.rb} +4 -4
- data/lib/n/{app → server}/script.rb +5 -5
- data/lib/n/{app → server}/server.rb +1 -1
- data/lib/n/{app → server}/session.rb +5 -5
- data/lib/n/{app → server}/user.rb +1 -1
- data/lib/n/{app/webrick-servlet.rb → server/webrick.rb} +77 -20
- data/lib/n/shaders.rb +3 -2
- data/lib/n/std.rb +5 -32
- data/test/n/{app → server}/tc_cookie.rb +2 -2
- data/test/n/server/tc_filters.rb +38 -0
- data/test/n/{app → server}/tc_request.rb +6 -6
- data/test/n/{app → server}/tc_requestpart.rb +3 -3
- data/test/n/{app → server}/tc_session.rb +2 -2
- data/test/n/tc_og.rb +178 -0
- data/test/n/ui/tc_pager.rb +3 -3
- metadata +41 -65
- data/examples/ndb/README +0 -5
- data/examples/ndb/run.rb +0 -271
- data/lib/n/app/webrick.rb +0 -73
- data/lib/n/db.rb +0 -233
- data/lib/n/db/README +0 -232
- data/lib/n/db/connection.rb +0 -365
- data/lib/n/db/managed.rb +0 -233
- data/lib/n/db/mixins.rb +0 -279
- data/lib/n/db/mysql.rb +0 -345
- data/lib/n/db/psql.rb +0 -383
- data/lib/n/db/tools.rb +0 -106
- data/lib/n/db/utils.rb +0 -102
- data/lib/n/server/PLAYBACK.txt +0 -8
- data/lib/n/server/RESEARCH.txt +0 -13
- data/test/n/tc_db.rb +0 -223
- data/test/n/tc_db_mysql.rb +0 -241
data/lib/n/db/tools.rb
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
# code:
|
2
|
-
# * George Moschovitis <gm@navel.gr>
|
3
|
-
# * Elias Athanasopoulos <elathan@navel.gr>
|
4
|
-
#
|
5
|
-
# (c) 2004 Navel, all rights reserved.
|
6
|
-
# $Id: tools.rb 99 2004-10-22 09:50:28Z gmosx $
|
7
|
-
|
8
|
-
module N;
|
9
|
-
|
10
|
-
require "n/db"
|
11
|
-
|
12
|
-
# = DbTools
|
13
|
-
#
|
14
|
-
# Useful methods wor working with the Db BAckend
|
15
|
-
#
|
16
|
-
module DbTools
|
17
|
-
|
18
|
-
# Lets say you have changed the definition of a managed object
|
19
|
-
# (for example you have added a new prop_accessor, and want to
|
20
|
-
# automatically update the database schema.
|
21
|
-
# Compares the given class to the actual db schema and
|
22
|
-
# automatically alters the backend table if needed.
|
23
|
-
# No need to optimize this method.
|
24
|
-
#
|
25
|
-
def self.alter_table(klass)
|
26
|
-
#
|
27
|
-
# Use the following query to see the fields in system level:
|
28
|
-
#
|
29
|
-
# sql = "SELECT attname, attnum FROM pg_attribute, pg_class "
|
30
|
-
# sql << "WHERE attrelid = pg_class.oid "
|
31
|
-
# sql << "AND relname = '#{klass::DBTABLE}' AND attnum > 0;"
|
32
|
-
#
|
33
|
-
# In orer to test alter_table() use the following tests:
|
34
|
-
#
|
35
|
-
# klass.__props << N::Property.new("new_field", String)
|
36
|
-
# klass.__props.delete_if{ |member| member.name == "new_field" }
|
37
|
-
#
|
38
|
-
# Remember you must not uncomment both of the above statements.
|
39
|
-
# Uncomment the first one, use alter_table(), the uncomment the
|
40
|
-
# seconde one and re-use alter_table().
|
41
|
-
#
|
42
|
-
$db.open { |db|
|
43
|
-
|
44
|
-
sql = "SELECT * FROM #{klass::DBTABLE} LIMIT 1;"
|
45
|
-
table_fields = db.exec(sql).fields
|
46
|
-
|
47
|
-
# find fields to be added.
|
48
|
-
properties_to_add = []
|
49
|
-
klass.__props.each { |klass_member|
|
50
|
-
properties_to_add << klass_member unless table_fields.include? klass_member.name
|
51
|
-
}
|
52
|
-
|
53
|
-
# find fields to be removed.
|
54
|
-
properties_to_remove = []
|
55
|
-
table_fields.each { |field|
|
56
|
-
properties_to_remove << field unless klass.__props.map{ |member| member.name }.include? field
|
57
|
-
}
|
58
|
-
|
59
|
-
# Add new fields
|
60
|
-
fields = []
|
61
|
-
properties_to_add.each { |p|
|
62
|
-
field = "#{p.symbol}"
|
63
|
-
if p.sql
|
64
|
-
field << " #{p.sql}"
|
65
|
-
else
|
66
|
-
field << " #{db.class::TYPEMAP[p.klass]}"
|
67
|
-
end
|
68
|
-
field << " #{p.sql}" if p.sql
|
69
|
-
|
70
|
-
fields << field
|
71
|
-
}
|
72
|
-
|
73
|
-
for field in fields
|
74
|
-
sql = "ALTER TABLE #{klass::DBTABLE} ADD COLUMN #{field}"
|
75
|
-
db.exec_clear(sql)
|
76
|
-
end
|
77
|
-
|
78
|
-
removed = nil
|
79
|
-
properties_to_remove.each { |p|
|
80
|
-
sql = "ALTER TABLE #{klass::DBTABLE} DROP COLUMN #{p} RESTRICT"
|
81
|
-
db.exec_clear(sql)
|
82
|
-
removed = true
|
83
|
-
}
|
84
|
-
|
85
|
-
if removed
|
86
|
-
sql = "UPDATE #{klass::DBTABLE}; VACUUM FULL #{klass::DBTABLE};"
|
87
|
-
db.exec_clear(sql)
|
88
|
-
end
|
89
|
-
|
90
|
-
}
|
91
|
-
end
|
92
|
-
|
93
|
-
# NOT IMPLEMENTED
|
94
|
-
#
|
95
|
-
def self.alter_column(klass, old_field, new_field)
|
96
|
-
end
|
97
|
-
|
98
|
-
# NOT IMPLEMENTED
|
99
|
-
#
|
100
|
-
def self.rename_table(old_klass, new_klass)
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
end # module
|
106
|
-
|
data/lib/n/db/utils.rb
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
# code:
|
2
|
-
# * George Moschovitis <gm@navel.gr>
|
3
|
-
# * Elias Athanasopoulos <elathan@navel.gr>
|
4
|
-
#
|
5
|
-
# (c) 2004 Navel, all rights reserved.
|
6
|
-
# $Id$
|
7
|
-
|
8
|
-
module N;
|
9
|
-
|
10
|
-
require "base64"
|
11
|
-
|
12
|
-
require "n/properties"
|
13
|
-
require "n/utils/array"
|
14
|
-
require "n/utils/time"
|
15
|
-
|
16
|
-
# = DbUtils
|
17
|
-
#
|
18
|
-
# A collection of Database utilities.
|
19
|
-
# Additional backend specific utilities are defined in
|
20
|
-
# the backend implementations.
|
21
|
-
#
|
22
|
-
module DbUtils
|
23
|
-
|
24
|
-
# Escape an sql string
|
25
|
-
#
|
26
|
-
def self.escape(str)
|
27
|
-
# defined in the backend
|
28
|
-
end
|
29
|
-
|
30
|
-
# Escape bytes
|
31
|
-
#
|
32
|
-
def self.escape_bytes(bytes)
|
33
|
-
# defined in the backend
|
34
|
-
end
|
35
|
-
|
36
|
-
# The name of the SQL table where entities of this class are stored.
|
37
|
-
# The Module separators are replaced with _ and NOT stripped out so
|
38
|
-
# that we can convert back to the original notation if needed.
|
39
|
-
#
|
40
|
-
def self.sql_table(klass)
|
41
|
-
return "_#{klass}".gsub(/::/, "_").downcase
|
42
|
-
end
|
43
|
-
|
44
|
-
# Convert a ruby time to an sql timestamp.
|
45
|
-
#
|
46
|
-
def self.sql_timestamp(time = Time.now)
|
47
|
-
# defined in the backend
|
48
|
-
end
|
49
|
-
|
50
|
-
# Output YYY-mm-dd
|
51
|
-
#
|
52
|
-
def self.sql_date(date)
|
53
|
-
# defined in the backend
|
54
|
-
end
|
55
|
-
|
56
|
-
# Parse sql datetime
|
57
|
-
#
|
58
|
-
def self.parse_sql_timestamp(str)
|
59
|
-
# defined in the backend
|
60
|
-
end
|
61
|
-
|
62
|
-
# Input YYYY-mm-dd
|
63
|
-
#
|
64
|
-
def self.parse_sql_date(str)
|
65
|
-
# defined in the backend
|
66
|
-
end
|
67
|
-
|
68
|
-
# Return an sql string evaluator for the property.
|
69
|
-
# No need to optimize this, used only to precalculate code.
|
70
|
-
#
|
71
|
-
# FIXME: add extra handling for float.
|
72
|
-
#--
|
73
|
-
# gmosx: base64 encoding is used because the unencode_bytea
|
74
|
-
# method of postgres is not implemented
|
75
|
-
#++
|
76
|
-
#
|
77
|
-
def self.write_prop(p)
|
78
|
-
if String == p.klass
|
79
|
-
return "'#\{DbUtils.escape(@#{p.symbol})\}'"
|
80
|
-
elsif Time == p.klass
|
81
|
-
return %|#\{@#{p.symbol} ? "'#\{DbUtils.sql_timestamp(@#{p.symbol})\}'" : 'NULL'\}|
|
82
|
-
elsif Date == p.klass
|
83
|
-
return %|#\{@#{p.symbol} ? "'#\{DbUtils.sql_date(@#{p.symbol})\}'" : 'NULL'\}|
|
84
|
-
elsif Object == p.klass or Array == p.klass or Hash == p.klass
|
85
|
-
#return "'#\{DbUtils.escape_bytes(Marshal.dump(@#{p.symbol}))\}'"
|
86
|
-
return "'#\{Base64.encode64(Marshal.dump(@#{p.symbol}))\}'"
|
87
|
-
else
|
88
|
-
# Fixnum, TrueClass
|
89
|
-
return "#\{@#{p.symbol} || 'NULL'\}"
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
# Return an evaluator for reading the property
|
94
|
-
# No need to optimize this, used only to precalculate code.
|
95
|
-
#
|
96
|
-
def self.read_prop(p)
|
97
|
-
# defined in the backend
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
end # module
|
102
|
-
|
data/lib/n/server/PLAYBACK.txt
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
overload the servers accept method to store socket data in RECORD mode
|
4
|
-
and read sockets from a previously recorded stream in PLAYBACK mode.
|
5
|
-
|
6
|
-
timing information must be stored along the socket data
|
7
|
-
|
8
|
-
the centralized accept methot makes the scheme possible.
|
data/lib/n/server/RESEARCH.txt
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
|
2
|
-
patterns: ObjectPool, ProducerConsumer
|
3
|
-
|
4
|
-
produced consumer pattern: listener produces sockets, thread pool consumes
|
5
|
-
sockets from a queue.
|
6
|
-
|
7
|
-
--
|
8
|
-
|
9
|
-
gmosx: daemons does not belong here ??
|
10
|
-
gmosx: do not use a thread per connection, use a pool of conections that service
|
11
|
-
a fifo list of connections (sockets).
|
12
|
-
|
13
|
-
gmosx: use a pipeline request handling architecture
|
data/test/n/tc_db.rb
DELETED
@@ -1,223 +0,0 @@
|
|
1
|
-
require "test/unit"
|
2
|
-
|
3
|
-
require "n/logger"; $log = Logger.new(STDERR) unless $log
|
4
|
-
|
5
|
-
require "n/db"
|
6
|
-
|
7
|
-
module Test # :nodoc: all
|
8
|
-
|
9
|
-
class Article
|
10
|
-
manage {
|
11
|
-
include N::Entity
|
12
|
-
|
13
|
-
prop_accessor String, :title, :body
|
14
|
-
}
|
15
|
-
|
16
|
-
def self.__descendants_classes
|
17
|
-
[Message]
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class Message
|
22
|
-
manage {
|
23
|
-
include N::Entity
|
24
|
-
include N::Named
|
25
|
-
include N::Child
|
26
|
-
include N::ParentClass
|
27
|
-
|
28
|
-
include N::Sequenced
|
29
|
-
|
30
|
-
prop_accessor Fixnum, :owner_oid
|
31
|
-
prop_accessor Fixnum, "smallint", :val1, :val2, :val3
|
32
|
-
prop_accessor String, :title, :body
|
33
|
-
prop_accessor String, "text NOT NULL", :test
|
34
|
-
prop_accessor Fixnum, :count
|
35
|
-
prop_accessor Time, :create_time
|
36
|
-
sql_index "owner_oid, pid"
|
37
|
-
|
38
|
-
# a marshaled property
|
39
|
-
prop_accessor Array, :options
|
40
|
-
}
|
41
|
-
|
42
|
-
def initialize
|
43
|
-
@create_time = Time.now
|
44
|
-
@options = []
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
class SubMessage < Message
|
50
|
-
manage {
|
51
|
-
# duplicate definition
|
52
|
-
prop_accessor Float, :count
|
53
|
-
}
|
54
|
-
end
|
55
|
-
|
56
|
-
class TC_N_Db < Test::Unit::TestCase
|
57
|
-
|
58
|
-
def setup
|
59
|
-
$db = N::Db.new(
|
60
|
-
:backend => "psql",
|
61
|
-
:address => "localhost",
|
62
|
-
:database => "test",
|
63
|
-
:user => "postgres",
|
64
|
-
:password => "navelrulez",
|
65
|
-
:connection_count => 2
|
66
|
-
)
|
67
|
-
|
68
|
-
@art = Article.new()
|
69
|
-
@art.title = "The parent"
|
70
|
-
@art.body = "The body"
|
71
|
-
|
72
|
-
@msg1 = Message.new()
|
73
|
-
@msg1.name = "name1"
|
74
|
-
@msg1.body = "body1"
|
75
|
-
@msg1.title = "title1"
|
76
|
-
@msg1.count = "22"
|
77
|
-
@msg1.owner_oid = 1
|
78
|
-
|
79
|
-
@msg2 = Message.new()
|
80
|
-
@msg2.name = "name2"
|
81
|
-
@msg2.body = "body2"
|
82
|
-
@msg2.title = "title2"
|
83
|
-
@msg2.count = "22"
|
84
|
-
@msg2.owner_oid = 2
|
85
|
-
end
|
86
|
-
|
87
|
-
def teardown
|
88
|
-
@art = @msg1 = @msg2 = nil
|
89
|
-
$db.shutdown()
|
90
|
-
end
|
91
|
-
|
92
|
-
# gmosx: hmm, implemented in one method to enforce order.
|
93
|
-
#
|
94
|
-
def test_all
|
95
|
-
$db.open { |db|
|
96
|
-
|
97
|
-
# check exception, cleanup test db.
|
98
|
-
|
99
|
-
db.drop_schema()
|
100
|
-
db.drop_table(Article)
|
101
|
-
db.drop_table(Message)
|
102
|
-
|
103
|
-
db.create_schema()
|
104
|
-
|
105
|
-
# bug: get methods without entity table
|
106
|
-
|
107
|
-
db.get(1, Message)
|
108
|
-
|
109
|
-
# check put
|
110
|
-
|
111
|
-
db << @art
|
112
|
-
# one oid is missed when creating the table for the first time!
|
113
|
-
assert_equal(1, @art.oid)
|
114
|
-
|
115
|
-
art2 = Article.new()
|
116
|
-
art2.title = "Another test"
|
117
|
-
db << art2
|
118
|
-
|
119
|
-
@msg1.set_parent(@art)
|
120
|
-
@msg1.options << "test"
|
121
|
-
@msg1.options << "value"
|
122
|
-
@msg1.options << "exit"
|
123
|
-
@msg2.set_parent(@art)
|
124
|
-
|
125
|
-
db << @msg1
|
126
|
-
db << @msg2
|
127
|
-
|
128
|
-
assert_equal(2, @msg2.oid)
|
129
|
-
|
130
|
-
# check marshaling
|
131
|
-
|
132
|
-
msg = db.get(1, Message)
|
133
|
-
assert_equal("value", msg.options[1])
|
134
|
-
# check children.
|
135
|
-
|
136
|
-
msgs = db.children(@art, Message, "ORDER BY count")
|
137
|
-
assert_equal(2, msgs.size())
|
138
|
-
assert_equal(Message, msgs[0].class)
|
139
|
-
|
140
|
-
assert_equal(2, db.count_children(@art, Message))
|
141
|
-
|
142
|
-
# bug: pid was string
|
143
|
-
|
144
|
-
assert_equal(@art.oid, msgs[0].pid)
|
145
|
-
|
146
|
-
# check updates
|
147
|
-
|
148
|
-
@art.title = "CHANGED TITLE"
|
149
|
-
db.update_properties("title='#{@art.title}'", @art)
|
150
|
-
|
151
|
-
art2 = db.get(@art.oid, Article)
|
152
|
-
|
153
|
-
assert_equal(art2.title, @art.title)
|
154
|
-
|
155
|
-
@art.body = "CHANGED BODY"
|
156
|
-
@art.title = "CHANGED AGAIN"
|
157
|
-
db << @art
|
158
|
-
|
159
|
-
art2 = db.get(@art.oid, Article)
|
160
|
-
assert_equal(art2.body, @art.body)
|
161
|
-
assert_equal(art2.title, "CHANGED AGAIN")
|
162
|
-
|
163
|
-
# check timestamp
|
164
|
-
|
165
|
-
now = Time.now()
|
166
|
-
@msg1.create_time = now
|
167
|
-
db << @msg1
|
168
|
-
|
169
|
-
msg = db.get(@msg1.oid, Message)
|
170
|
-
|
171
|
-
# bug:
|
172
|
-
# assert_equal(msg.create_time, @msg1.create_time)
|
173
|
-
assert_equal(msg.create_time.to_i(), @msg1.create_time.to_i())
|
174
|
-
|
175
|
-
# gmosx: not implemented in postgres driver.
|
176
|
-
# classes = db.managed_classes()
|
177
|
-
# assert_equal(2, classes.size())
|
178
|
-
|
179
|
-
# get_by_name
|
180
|
-
|
181
|
-
msg = db.get_by_name("name2", Message)
|
182
|
-
assert_equal("body2", msg.body)
|
183
|
-
|
184
|
-
# pclass
|
185
|
-
|
186
|
-
assert_equal(@art.class.to_s(), msg.pclass)
|
187
|
-
|
188
|
-
}
|
189
|
-
|
190
|
-
# deserialize = false
|
191
|
-
|
192
|
-
$db.open(deserialize = false) { |db|
|
193
|
-
|
194
|
-
assert_equal(false, db.deserialize)
|
195
|
-
|
196
|
-
msg = db.get_by_name("name2", Message)
|
197
|
-
assert_equal(Array, msg.class)
|
198
|
-
|
199
|
-
art = db.get(2, Article)
|
200
|
-
assert_equal(Array, art.class)
|
201
|
-
|
202
|
-
}
|
203
|
-
|
204
|
-
# cascade delete
|
205
|
-
|
206
|
-
msgs = $db.children(0, Message)
|
207
|
-
assert_equal(2, msgs.size())
|
208
|
-
|
209
|
-
$db.delete(@art)
|
210
|
-
|
211
|
-
msgs = $db.children(0, Message)
|
212
|
-
assert_equal(nil, msgs)
|
213
|
-
|
214
|
-
end
|
215
|
-
|
216
|
-
def test_sql_table_to_class
|
217
|
-
# assert_equal(Article,
|
218
|
-
# N::DbUtils.sql_table_to_class(N::DbUtils.sql_table(Article)))
|
219
|
-
end
|
220
|
-
|
221
|
-
end
|
222
|
-
|
223
|
-
end
|