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/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
|
-
|