og 0.5.0 → 0.6.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/README.og +2 -1
- data/RELEASES.og +10 -0
- data/examples/og/run.rb +41 -2
- data/lib/glue.rb +1 -1
- data/lib/glue/property.rb +9 -3
- data/lib/og.rb +25 -17
- data/lib/og/backend.rb +15 -3
- data/lib/og/backends/mysql.rb +30 -3
- data/lib/og/backends/psql.rb +44 -3
- data/lib/og/meta.rb +117 -10
- data/lib/og/version.rb +2 -2
- metadata +2 -2
data/README.og
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Og 0.
|
1
|
+
= Og 0.6.0
|
2
2
|
|
3
3
|
Og (ObjectGraph) is an efficient, yet simple object-relational mapping
|
4
4
|
library. Og provides transparent serialization of object graphs to a RDBMS
|
@@ -28,6 +28,7 @@ The library provides the following features:
|
|
28
28
|
+ Absolutely no configuration files.
|
29
29
|
+ Multiple backends (PostgreSQL, MySQL).
|
30
30
|
+ ActiveRecord-style meta language and db aware methods.
|
31
|
+
+ Automatially generates join-tables for many_to_many relations.
|
31
32
|
+ Deserialize to Ruby Objects or ResultSets.
|
32
33
|
+ Deserialize sql join queries to Ruby Objects.
|
33
34
|
+ Serialize arbitrary ruby object graphs through YAML.
|
data/RELEASES.og
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== Version 0.6 was released on 13/12/2004.
|
2
|
+
|
3
|
+
This is a preview release, the api for the new features is not
|
4
|
+
finalized. This early release gives other developers to offer suggestions
|
5
|
+
on the final form of those features.
|
6
|
+
|
7
|
+
Most notable additions:
|
8
|
+
|
9
|
+
* Og many_to_many relations with auto generation of the join table.
|
10
|
+
* Og has_one relation.
|
1
11
|
|
2
12
|
== Version 0.5.0 was released on 21/11/2004.
|
3
13
|
|
data/examples/og/run.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
# * George Moschovitis <gm@navel.gr>
|
7
7
|
#
|
8
8
|
# (c) 2004 Navel, all rights reserved.
|
9
|
-
# $Id: run.rb
|
9
|
+
# $Id: run.rb 185 2004-12-10 13:29:09Z gmosx $
|
10
10
|
|
11
11
|
$:.unshift "../../lib"
|
12
12
|
|
@@ -55,6 +55,7 @@ class User
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
|
58
59
|
# = A parent class
|
59
60
|
#
|
60
61
|
class Article
|
@@ -95,6 +96,21 @@ class Article
|
|
95
96
|
end
|
96
97
|
end
|
97
98
|
|
99
|
+
# = A parent class
|
100
|
+
#
|
101
|
+
class Category
|
102
|
+
prop_accessor :title, String
|
103
|
+
prop_accessor :body, String
|
104
|
+
|
105
|
+
# define a 'many to many' relation.
|
106
|
+
many_to_many Article
|
107
|
+
|
108
|
+
def initialize(title = nil)
|
109
|
+
@title = title
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
98
114
|
# = Article comment
|
99
115
|
#
|
100
116
|
class ArticleComment < Comment
|
@@ -127,7 +143,6 @@ end
|
|
127
143
|
$log = Logger.new(STDERR);
|
128
144
|
|
129
145
|
# Og configuration.
|
130
|
-
|
131
146
|
config = {
|
132
147
|
:address => "localhost",
|
133
148
|
:database => "test",
|
@@ -249,3 +264,27 @@ part.save!
|
|
249
264
|
|
250
265
|
article.parts.each { |pa| puts pa }
|
251
266
|
|
267
|
+
puts "\n\n"
|
268
|
+
puts '---'
|
269
|
+
|
270
|
+
c1 = Category.new("Category1").save!
|
271
|
+
c2 = Category.new("Category2").save!
|
272
|
+
|
273
|
+
article.add_category(c1)
|
274
|
+
article.add_category(c2)
|
275
|
+
|
276
|
+
puts '---'
|
277
|
+
|
278
|
+
article.categories.each { |c| puts c.title }
|
279
|
+
|
280
|
+
puts '---'
|
281
|
+
|
282
|
+
c2.articles.each { |a| puts a.title }
|
283
|
+
|
284
|
+
article.del_category(c1)
|
285
|
+
|
286
|
+
puts '---'
|
287
|
+
|
288
|
+
article.categories.each { |c| puts c.title }
|
289
|
+
|
290
|
+
|
data/lib/glue.rb
CHANGED
data/lib/glue/property.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# * Elias Karakoulakis <ekarak@ktismata.com>
|
6
6
|
#
|
7
7
|
# (c) 2004 Navel, all rights reserved.
|
8
|
-
# $Id: property.rb
|
8
|
+
# $Id: property.rb 185 2004-12-10 13:29:09Z gmosx $
|
9
9
|
|
10
10
|
require "glue/array"
|
11
11
|
require "glue/hash"
|
@@ -48,6 +48,10 @@ class Property
|
|
48
48
|
def ==(other)
|
49
49
|
return @symbol == other.symbol
|
50
50
|
end
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
return name
|
54
|
+
end
|
51
55
|
end
|
52
56
|
|
53
57
|
end # module
|
@@ -236,6 +240,8 @@ class Module
|
|
236
240
|
}
|
237
241
|
end
|
238
242
|
|
243
|
+
# gmosx: __force_xxx reuses xxx= to allow for easier
|
244
|
+
# overrides.
|
239
245
|
if writer
|
240
246
|
module_eval %{
|
241
247
|
def #{s}=(val)
|
@@ -243,7 +249,7 @@ class Module
|
|
243
249
|
end
|
244
250
|
|
245
251
|
def __force_#{s}(val)
|
246
|
-
|
252
|
+
self.#{s}=(} + case klass.name
|
247
253
|
when Fixnum.name
|
248
254
|
"val.to_i()"
|
249
255
|
when String.name
|
@@ -256,7 +262,7 @@ class Module
|
|
256
262
|
"val.to_i() > 0"
|
257
263
|
else
|
258
264
|
"val"
|
259
|
-
end + %{
|
265
|
+
end + %{)
|
260
266
|
end
|
261
267
|
}
|
262
268
|
end
|
data/lib/og.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# * George Moschovitis <gm@navel.gr>
|
3
3
|
#
|
4
4
|
# (c) 2004 Navel, all rights reserved.
|
5
|
-
# $Id: og.rb
|
5
|
+
# $Id: og.rb 185 2004-12-10 13:29:09Z gmosx $
|
6
6
|
|
7
7
|
require "glue/property"
|
8
8
|
require "glue/array"
|
@@ -10,6 +10,24 @@ require "glue/hash"
|
|
10
10
|
require "glue/time"
|
11
11
|
require "glue/pool"
|
12
12
|
|
13
|
+
# If true, only allow reading from the database. Usefull
|
14
|
+
# for maintainance.
|
15
|
+
#
|
16
|
+
$og_read_only_mode = false
|
17
|
+
|
18
|
+
# If true, the library automatically 'enchants' managed classes.
|
19
|
+
# In enchant mode, special db aware methods are added to
|
20
|
+
# managed classes and instances.
|
21
|
+
#
|
22
|
+
$og_enchant_managed_classes = true
|
23
|
+
|
24
|
+
# If true, use Ruby's advanced introspection capabilities to
|
25
|
+
# automatically manage classes tha define properties.
|
26
|
+
$og_auto_manage_classes = true
|
27
|
+
|
28
|
+
# If true, automatically include the Og meta-language into Module.
|
29
|
+
$og_include_meta_language = true
|
30
|
+
|
13
31
|
require "og/meta"
|
14
32
|
|
15
33
|
# = Og
|
@@ -93,21 +111,6 @@ require "og/meta"
|
|
93
111
|
#
|
94
112
|
module Og
|
95
113
|
|
96
|
-
# If true, only allow reading from the database. Usefull
|
97
|
-
# for maintainance.
|
98
|
-
#
|
99
|
-
$og_read_only_mode = false
|
100
|
-
|
101
|
-
# If true, the library automatically 'enchants' managed classes.
|
102
|
-
# In enchant mode, special db aware methods are added to
|
103
|
-
# managed classes and instances.
|
104
|
-
#
|
105
|
-
$og_enchant_managed_classes = true
|
106
|
-
|
107
|
-
# If true, use Ruby's advanced introspection capabilities to
|
108
|
-
# automatically manage classes tha define properties.
|
109
|
-
$og_auto_manage_classes = true
|
110
|
-
|
111
114
|
# = Unmanageable
|
112
115
|
#
|
113
116
|
# Marker module. If included this in a class, the Og automanager
|
@@ -328,7 +331,11 @@ class Database
|
|
328
331
|
def self.all(extra_sql = nil)
|
329
332
|
$og.load_all(#{klass}, extra_sql)
|
330
333
|
end
|
331
|
-
|
334
|
+
|
335
|
+
def self.count(sql = "SELECT COUNT(*) FROM #{klass::DBTABLE}")
|
336
|
+
$og.count(sql, #{klass})
|
337
|
+
end
|
338
|
+
|
332
339
|
def self.select(sql)
|
333
340
|
$og.select(sql, #{klass})
|
334
341
|
end
|
@@ -343,6 +350,7 @@ class Database
|
|
343
350
|
|
344
351
|
def save
|
345
352
|
$og << self
|
353
|
+
return self
|
346
354
|
end
|
347
355
|
alias_method :save!, :save
|
348
356
|
|
data/lib/og/backend.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# * George Moschovitis <gm@navel.gr>
|
3
3
|
#
|
4
4
|
# (c) 2004 Navel, all rights reserved.
|
5
|
-
# $Id: backend.rb
|
5
|
+
# $Id: backend.rb 185 2004-12-10 13:29:09Z gmosx $
|
6
6
|
|
7
7
|
require "yaml"
|
8
8
|
|
@@ -16,15 +16,27 @@ module Og
|
|
16
16
|
#
|
17
17
|
module Utils
|
18
18
|
|
19
|
-
#
|
19
|
+
# Encode the name of the klass as an sql safe string.
|
20
20
|
# The Module separators are replaced with _ and NOT stripped out so
|
21
21
|
# that we can convert back to the original notation if needed.
|
22
22
|
# The leading module if available is removed.
|
23
23
|
#
|
24
|
+
def self.encode(klass)
|
25
|
+
"#{klass.name.gsub(/^.*::/, "")}".gsub(/::/, "_").downcase
|
26
|
+
end
|
27
|
+
|
28
|
+
# The name of the SQL table where objects of this class are stored.
|
29
|
+
#
|
24
30
|
def self.table(klass)
|
25
|
-
|
31
|
+
"_#{encode(klass)}"
|
26
32
|
end
|
27
33
|
|
34
|
+
# The name of the join table for the two given classes.
|
35
|
+
#
|
36
|
+
def self.join_table(klass1, klass2)
|
37
|
+
"_j_#{Og::Utils.encode(klass1)}_#{Og::Utils.encode(klass2)}"
|
38
|
+
end
|
39
|
+
|
28
40
|
# Returns the props that will be included in the insert query.
|
29
41
|
# For some backends the oid should be stripped.
|
30
42
|
#
|
data/lib/og/backends/mysql.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# * Elias Athanasopoulos <elathan@navel.gr>
|
4
4
|
#
|
5
5
|
# (c) 2004 Navel, all rights reserved.
|
6
|
-
# $Id: mysql.rb
|
6
|
+
# $Id: mysql.rb 185 2004-12-10 13:29:09Z gmosx $
|
7
7
|
|
8
8
|
require "mysql"
|
9
9
|
|
@@ -302,14 +302,41 @@ class MysqlBackend < Og::Backend
|
|
302
302
|
|
303
303
|
# Create indices
|
304
304
|
|
305
|
-
if klass.__meta
|
306
|
-
for data in
|
305
|
+
if klass.__meta and indices = klass.__meta[:sql_index]
|
306
|
+
for data in indices
|
307
307
|
idx, options = *data
|
308
308
|
idx = idx.to_s
|
309
309
|
pre_sql, post_sql = options[:pre], options[:post]
|
310
310
|
idxname = idx.gsub(/ /, "").gsub(/,/, "_").gsub(/\(.*\)/, "")
|
311
311
|
exec "CREATE #{pre_sql} INDEX #{klass::DBTABLE}_#{idxname}_idx #{post_sql} ON #{klass::DBTABLE} (#{idx})"
|
312
312
|
end
|
313
|
+
end
|
314
|
+
|
315
|
+
# Create join tables if needed. Join tables are used in
|
316
|
+
# 'many_to_many' relations.
|
317
|
+
|
318
|
+
if klass.__meta and joins = klass.__meta[:sql_join]
|
319
|
+
for data in joins
|
320
|
+
# the class to join to and some options.
|
321
|
+
join_class, options = *data
|
322
|
+
|
323
|
+
# gmosx: dont use DBTABLE here, perhaps the join class
|
324
|
+
# is not managed yet.
|
325
|
+
join_table = "#{Og::Utils.join_table(klass, join_class)}"
|
326
|
+
join_src = "#{Og::Utils.encode(klass)}_oid"
|
327
|
+
join_dst = "#{Og::Utils.encode(join_class)}_oid"
|
328
|
+
begin
|
329
|
+
exec "CREATE TABLE #{join_table} ( key1 integer, key2 integer )"
|
330
|
+
exec "CREATE INDEX #{join_table}_key1_idx ON #{join_table} (key1)"
|
331
|
+
exec "CREATE INDEX #{join_table}_key2_idx ON #{join_table} (key2)"
|
332
|
+
rescue => ex
|
333
|
+
if ex.errno == 1050 # table already exists.
|
334
|
+
$log.debug "Join table already exists" if $DBG
|
335
|
+
else
|
336
|
+
raise
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
313
340
|
end
|
314
341
|
end
|
315
342
|
|
data/lib/og/backends/psql.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# * George Moschovitis <gm@navel.gr>
|
3
3
|
#
|
4
4
|
# (c) 2004 Navel, all rights reserved.
|
5
|
-
# $Id: psql.rb
|
5
|
+
# $Id: psql.rb 185 2004-12-10 13:29:09Z gmosx $
|
6
6
|
|
7
7
|
require "postgres"
|
8
8
|
|
@@ -268,8 +268,8 @@ class PsqlBackend < Og::Backend
|
|
268
268
|
|
269
269
|
# Create indices
|
270
270
|
|
271
|
-
if klass.__meta
|
272
|
-
for data in
|
271
|
+
if klass.__meta and indices = klass.__meta[:sql_index]
|
272
|
+
for data in indices
|
273
273
|
idx, options = *data
|
274
274
|
idx = idx.to_s
|
275
275
|
pre_sql, post_sql = options[:pre], options[:post]
|
@@ -304,6 +304,47 @@ class PsqlBackend < Og::Backend
|
|
304
304
|
raise
|
305
305
|
end
|
306
306
|
end
|
307
|
+
|
308
|
+
# Create join tables if needed. Join tables are used in
|
309
|
+
# 'many_to_many' relations.
|
310
|
+
|
311
|
+
if klass.__meta and joins = klass.__meta[:sql_join]
|
312
|
+
for data in joins
|
313
|
+
# the class to join to and some options.
|
314
|
+
join_class, options = *data
|
315
|
+
|
316
|
+
# gmosx: dont use DBTABLE here, perhaps the join class
|
317
|
+
# is not managed yet.
|
318
|
+
join_table = "#{Og::Utils.join_table(klass, join_class)}"
|
319
|
+
join_src = "#{Og::Utils.encode(klass)}_oid"
|
320
|
+
join_dst = "#{Og::Utils.encode(join_class)}_oid"
|
321
|
+
begin
|
322
|
+
exec "CREATE TABLE #{join_table} ( key1 integer, key2 integer )"
|
323
|
+
exec "CREATE INDEX #{join_table}_key1_idx ON #{join_table} (key1)"
|
324
|
+
exec "CREATE INDEX #{join_table}_key2_idx ON #{join_table} (key2)"
|
325
|
+
rescue => ex
|
326
|
+
# gmosx: any idea how to better test this?
|
327
|
+
if ex.to_s =~ /relation .* already exists/i
|
328
|
+
$log.debug "Join table already exists" if $DBG
|
329
|
+
else
|
330
|
+
raise
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
begin
|
337
|
+
exec(sql)
|
338
|
+
$log.info "Created join table '#{join_table}'."
|
339
|
+
rescue => ex
|
340
|
+
# gmosx: any idea how to better test this?
|
341
|
+
if ex.to_s =~ /relation .* already exists/i
|
342
|
+
$log.debug "Join table already exists" if $DBG
|
343
|
+
else
|
344
|
+
raise
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
307
348
|
end
|
308
349
|
|
309
350
|
# Drop the managed object table
|
data/lib/og/meta.rb
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
# * George Moschovitis <gm@navel.gr>
|
3
3
|
#
|
4
4
|
# (c) 2004 Navel, all rights reserved.
|
5
|
-
# $Id: meta.rb
|
5
|
+
# $Id: meta.rb 185 2004-12-10 13:29:09Z gmosx $
|
6
6
|
|
7
7
|
require 'og/backend'
|
8
|
+
require 'glue/inflector'
|
8
9
|
|
9
10
|
module Og
|
10
11
|
|
@@ -68,15 +69,13 @@ module MetaLanguage
|
|
68
69
|
}
|
69
70
|
end
|
70
71
|
|
71
|
-
# Implements a '
|
72
|
+
# Implements a 'has_one' relation.
|
72
73
|
# Automatically enchants the calling class with helper methods.
|
73
74
|
#
|
74
|
-
# NOT IMPLEMENTED.
|
75
|
-
#
|
76
75
|
# Example:
|
77
76
|
#
|
78
77
|
# class MyObject
|
79
|
-
#
|
78
|
+
# has_one :children, AnotherObject
|
80
79
|
# end
|
81
80
|
#
|
82
81
|
# creates the code:
|
@@ -84,10 +83,23 @@ module MetaLanguage
|
|
84
83
|
# def children; ... end
|
85
84
|
#
|
86
85
|
def has_one(klass, name, options = {})
|
86
|
+
# linkback is the property of the child object that 'links back'
|
87
|
+
# to this object.
|
88
|
+
linkback = options[:linkback] || "#{MetaUtils.expand(self)}_oid"
|
89
|
+
|
87
90
|
module_eval %{
|
91
|
+
@@og_descendants ||= {}
|
92
|
+
@@og_descendants[#{klass}] = :#{linkback}
|
93
|
+
|
94
|
+
unless defined?(og_descendants)
|
95
|
+
def self.og_descendants
|
96
|
+
@@og_descendants
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
88
100
|
def #{name}(extrasql = nil)
|
89
|
-
$og.select_one("
|
90
|
-
end
|
101
|
+
$og.select_one("SELECT * FROM #{Utils.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}", #{klass})
|
102
|
+
end
|
91
103
|
}
|
92
104
|
end
|
93
105
|
|
@@ -97,7 +109,7 @@ module MetaLanguage
|
|
97
109
|
# Example:
|
98
110
|
#
|
99
111
|
# class MyObject
|
100
|
-
# has_many
|
112
|
+
# has_many :children, AnotherObject
|
101
113
|
# end
|
102
114
|
#
|
103
115
|
# creates the code:
|
@@ -129,11 +141,106 @@ module MetaLanguage
|
|
129
141
|
}
|
130
142
|
end
|
131
143
|
|
144
|
+
# Implements a 'many_to_many' relation.
|
145
|
+
# Two objects are associated using an intermediate join table.
|
146
|
+
# Automatically enchants the calling class with helper methods.
|
147
|
+
#
|
148
|
+
# Example:
|
149
|
+
#
|
150
|
+
# class Article
|
151
|
+
# many_to_many :children, Categories
|
152
|
+
# end
|
153
|
+
#
|
154
|
+
# article.categories
|
155
|
+
# article.del_category
|
156
|
+
# article.add_category
|
157
|
+
# article.clear_categories
|
158
|
+
#
|
159
|
+
# category.articles
|
160
|
+
# ...
|
161
|
+
#
|
162
|
+
#--
|
163
|
+
# FIXME: make more compatible with other enchant methods.
|
164
|
+
#++
|
165
|
+
def many_to_many(klass, options = {})
|
166
|
+
name1 = options[:name1] || G::Inflector.name(self)
|
167
|
+
pname1 = options[:list_name1] || G::Inflector.plural_name(self)
|
168
|
+
name2 = options[:name2] || G::Inflector.name(klass)
|
169
|
+
pname2 = options[:list_name2] || G::Inflector.plural_name(klass)
|
170
|
+
|
171
|
+
# exit if the class is allready indirectly 'enchanted' from the
|
172
|
+
# other class of the many_to_many relation.
|
173
|
+
return if self.respond_to?(name1)
|
174
|
+
|
175
|
+
# Add some metadata to the class to allow for automatic join table
|
176
|
+
# calculation.
|
177
|
+
meta :sql_join, [klass, options]
|
178
|
+
|
179
|
+
# gmosx, FIXME: should I update descendants here ?
|
180
|
+
|
181
|
+
# enchant this class
|
182
|
+
|
183
|
+
module_eval %{
|
184
|
+
def #{pname2}(extrasql = nil)
|
185
|
+
$og.select("SELECT d.* FROM #{Utils.table(klass)} AS d, #{Utils.join_table(self, klass)} AS j WHERE j.key1=\#\@oid AND j.key2=d.oid \#\{extrasql\}", #{klass})
|
186
|
+
end
|
187
|
+
|
188
|
+
def #{pname2}_count(extrasql = nil)
|
189
|
+
$og.select("SELECT COUNT(*) FROM #{Utils.table(klass)} AS d, #{Utils.join_table(self, klass)} AS j WHERE j.key1=\#\@oid AND j.key2=d.oid \#\{extrasql\}", #{klass})
|
190
|
+
end
|
191
|
+
|
192
|
+
def add_#{name2}(obj, extra = nil)
|
193
|
+
$og.exec("INSERT INTO #{Utils.join_table(self, klass)} (key1, key2) VALUES (\#\@oid, \#\{obj.oid\})")
|
194
|
+
end
|
195
|
+
|
196
|
+
def del_#{name2}(obj_or_oid, extra = nil)
|
197
|
+
$og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key2=\#\{obj_or_oid.to_i\}")
|
198
|
+
end
|
199
|
+
alias_method :delete_#{name2}, :del_#{name2}
|
200
|
+
|
201
|
+
def clear_#{pname2}
|
202
|
+
$og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key1=\#\@oid")
|
203
|
+
end
|
204
|
+
}
|
205
|
+
|
206
|
+
# indirectly enchant the other class of the relation.
|
207
|
+
|
208
|
+
klass.module_eval %{
|
209
|
+
def #{pname1}(extrasql = nil)
|
210
|
+
$og.select("SELECT s.* FROM #{Utils.table(self)} AS s, #{Utils.join_table(self, klass)} AS j WHERE j.key2=\#\@oid AND j.key1=s.oid \#\{extrasql\}", #{self})
|
211
|
+
end
|
212
|
+
|
213
|
+
def #{pname1}_count(extrasql = nil)
|
214
|
+
$og.select("SELECT COUNT(*) FROM #{Utils.table(self)} AS s, #{Utils.join_table(self, klass)} AS j WHERE j.key2=\#\@oid AND j.key1=s.oid \#\{extrasql\}", #{self})
|
215
|
+
end
|
216
|
+
|
217
|
+
def add_#{name1}(obj, extra = nil)
|
218
|
+
$og.exec("INSERT INTO #{Utils.join_table(self, klass)} (key1, key2) VALUES (\#\{obj.oid\}, \#\@oid)")
|
219
|
+
end
|
220
|
+
|
221
|
+
def del_#{name1}(obj_or_oid, extra = nil)
|
222
|
+
$og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key1=\#\{obj_or_oid.to_i\}")
|
223
|
+
end
|
224
|
+
alias_method :delete_#{name1}, :del_#{name1}
|
225
|
+
|
226
|
+
def clear_#{pname1}
|
227
|
+
$og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key2=\#\@oid")
|
228
|
+
end
|
229
|
+
}
|
230
|
+
end
|
231
|
+
alias :has_and_belongs_to_many :many_to_many
|
232
|
+
|
132
233
|
end
|
133
234
|
|
134
235
|
end # module
|
135
236
|
|
136
|
-
|
137
|
-
|
237
|
+
# Include the meta-language extensions into Module. If the flag is
|
238
|
+
# false the developer is responsible for including the MetaLanguage
|
239
|
+
# module where needed.
|
240
|
+
#
|
241
|
+
if $og_include_meta_language
|
242
|
+
class Module # :nodoc: all
|
243
|
+
include Og::MetaLanguage
|
244
|
+
end
|
138
245
|
end
|
139
246
|
|
data/lib/og/version.rb
CHANGED