og 0.18.1 → 0.19.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 +123 -0
- data/README +13 -2
- data/doc/AUTHORS +4 -1
- data/doc/RELEASES +72 -1
- data/examples/run.rb +3 -3
- data/lib/og.rb +8 -1
- data/lib/og/collection.rb +3 -0
- data/lib/og/entity.rb +27 -7
- data/lib/og/manager.rb +46 -3
- data/lib/og/mixin/optimistic_locking.rb +59 -0
- data/lib/og/relation.rb +53 -4
- data/lib/og/relation/has_many.rb +16 -0
- data/lib/og/store.rb +4 -4
- data/lib/og/store/mysql.rb +19 -5
- data/lib/og/store/psql.rb +39 -0
- data/lib/og/store/sql.rb +165 -47
- data/lib/og/store/sqlite.rb +21 -5
- data/test/og/mixin/tc_optimistic_locking.rb +56 -0
- data/test/og/tc_inheritance.rb +103 -0
- data/test/og/tc_polymorphic.rb +64 -0
- data/test/og/tc_store.rb +44 -10
- metadata +7 -4
- data/lib/og/store/madeleine.rb +0 -2
data/lib/og/store/sqlite.rb
CHANGED
@@ -57,8 +57,7 @@ class SqliteStore < SqlStore
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def close
|
60
|
-
|
61
|
-
# @conn.close
|
60
|
+
@conn.close
|
62
61
|
super
|
63
62
|
end
|
64
63
|
|
@@ -96,6 +95,15 @@ class SqliteStore < SqlStore
|
|
96
95
|
@conn.rollback if @transaction_nesting < 1
|
97
96
|
end
|
98
97
|
|
98
|
+
def last_insert_rowid
|
99
|
+
conn.query("SELECT last_insert_rowid()").first_value.to_i
|
100
|
+
end
|
101
|
+
|
102
|
+
def sql_update(sql)
|
103
|
+
exec(sql)
|
104
|
+
@conn.changes
|
105
|
+
end
|
106
|
+
|
99
107
|
private
|
100
108
|
|
101
109
|
def create_table(klass)
|
@@ -161,7 +169,7 @@ private
|
|
161
169
|
res = @conn.query "SELECT * FROM #{klass::OGTABLE} LIMIT 1"
|
162
170
|
map = {}
|
163
171
|
|
164
|
-
fields = res.
|
172
|
+
fields = res.columns
|
165
173
|
|
166
174
|
fields.size.times do |i|
|
167
175
|
map[fields[i].intern] = i
|
@@ -176,14 +184,19 @@ private
|
|
176
184
|
pk = klass.primary_key.first
|
177
185
|
props = klass.properties
|
178
186
|
values = props.collect { |p| write_prop(p) }.join(',')
|
187
|
+
|
188
|
+
if klass.metadata.superclass or klass.metadata.subclasses
|
189
|
+
props << Property.new(:ogtype, String)
|
190
|
+
values << ", '#{klass}'"
|
191
|
+
end
|
179
192
|
|
180
193
|
sql = "INSERT INTO #{klass::OGTABLE} (#{props.collect {|p| p.symbol.to_s}.join(',')}) VALUES (#{values})"
|
181
194
|
|
182
195
|
klass.class_eval %{
|
183
196
|
def og_insert(store)
|
184
197
|
#{Aspects.gen_advice_code(:og_insert, klass.advices, :pre) if klass.respond_to?(:advices)}
|
185
|
-
store.
|
186
|
-
@#{pk} = store.
|
198
|
+
store.query("#{sql}").close
|
199
|
+
@#{pk} = store.last_insert_rowid
|
187
200
|
#{Aspects.gen_advice_code(:og_insert, klass.advices, :post) if klass.respond_to?(:advices)}
|
188
201
|
end
|
189
202
|
}
|
@@ -192,3 +205,6 @@ private
|
|
192
205
|
end
|
193
206
|
|
194
207
|
end
|
208
|
+
|
209
|
+
# * George Moschovitis <gm@navel.gr>
|
210
|
+
# * Ghislain Mary
|
@@ -0,0 +1,56 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
2
|
+
|
3
|
+
$DBG = true
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
|
7
|
+
require 'og'
|
8
|
+
require 'og/mixin/optimistic_locking'
|
9
|
+
|
10
|
+
$og = Og.setup(
|
11
|
+
:store => 'psql',
|
12
|
+
:name => 'test',
|
13
|
+
:user => 'postgres',
|
14
|
+
:password => 'navelrulez',
|
15
|
+
:destroy => true
|
16
|
+
)
|
17
|
+
|
18
|
+
class TC_OgLocking < Test::Unit::TestCase # :nodoc: all
|
19
|
+
include Og
|
20
|
+
|
21
|
+
class Article
|
22
|
+
property :body, String
|
23
|
+
include Og::Locking
|
24
|
+
|
25
|
+
def initialize(body)
|
26
|
+
@body = body
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_all
|
31
|
+
$og.manage_classes
|
32
|
+
|
33
|
+
Article.create('test')
|
34
|
+
|
35
|
+
a = Article[1]
|
36
|
+
|
37
|
+
b = Article[1]
|
38
|
+
|
39
|
+
a.body = 'Changed'
|
40
|
+
assert_nothing_raised do
|
41
|
+
a.save
|
42
|
+
end
|
43
|
+
|
44
|
+
b.body = 'Ooops'
|
45
|
+
assert_raise(Og::StaleObjectError) do
|
46
|
+
b.update
|
47
|
+
end
|
48
|
+
|
49
|
+
c = Article[1]
|
50
|
+
a.body = 'Changed again'
|
51
|
+
assert_nothing_raised do
|
52
|
+
a.update
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), 'lib')
|
2
|
+
|
3
|
+
$DBG = true
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
|
7
|
+
require 'og'
|
8
|
+
|
9
|
+
class TC_OgInheritance < Test::Unit::TestCase # :nodoc: all
|
10
|
+
include Og
|
11
|
+
|
12
|
+
class Document
|
13
|
+
property :title, String
|
14
|
+
schema_inheritance
|
15
|
+
|
16
|
+
def initialize(title)
|
17
|
+
@title = title
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Article < Document
|
22
|
+
property :body, String
|
23
|
+
|
24
|
+
def initialize(title, body)
|
25
|
+
@title, @body = title, body
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Photo < Document
|
30
|
+
property :url, String
|
31
|
+
|
32
|
+
def initialize(title, url)
|
33
|
+
@title, @url = title, url
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_all
|
38
|
+
=begin
|
39
|
+
@og = Og.setup(
|
40
|
+
:store => :memory,
|
41
|
+
:name => :test
|
42
|
+
)
|
43
|
+
=end
|
44
|
+
#=begin
|
45
|
+
@og = Og.setup(
|
46
|
+
:destroy => true,
|
47
|
+
:store => :sqlite,
|
48
|
+
:name => 'test'
|
49
|
+
)
|
50
|
+
#=end
|
51
|
+
=begin
|
52
|
+
@og = Og.setup(
|
53
|
+
:destroy => true,
|
54
|
+
:store => :mysql,
|
55
|
+
:name => 'test',
|
56
|
+
:user => 'root',
|
57
|
+
:password => 'navelrulez'
|
58
|
+
)
|
59
|
+
=end
|
60
|
+
assert_equal [Document], Photo.metadata.superclass
|
61
|
+
assert_equal [Photo, Article], Document.metadata.subclasses
|
62
|
+
|
63
|
+
assert Document.metadata.schema_inheritance
|
64
|
+
|
65
|
+
# propagate schema_inheritance flag.
|
66
|
+
|
67
|
+
assert Photo.metadata.schema_inheritance
|
68
|
+
|
69
|
+
# subclasses reuse the same table.
|
70
|
+
|
71
|
+
assert_equal Document.table, Photo.table
|
72
|
+
|
73
|
+
doc = Document.create('doc1')
|
74
|
+
Photo.create('photo1', 'http:/www.gmosx.com/photo/1')
|
75
|
+
Photo.create('photo2', 'http:/www.gmosx.com/photo/2')
|
76
|
+
Article.create('art1', 'here comes the body')
|
77
|
+
Article.create('art2', 'this is cool')
|
78
|
+
Article.create('art3', 'this is cooler')
|
79
|
+
|
80
|
+
docs = Document.all
|
81
|
+
|
82
|
+
assert_equal 6, docs.size
|
83
|
+
assert_equal 'art2', docs[4].title
|
84
|
+
|
85
|
+
assert_equal Document, docs[0].class
|
86
|
+
assert_equal Photo, docs[1].class
|
87
|
+
assert_equal Article, docs[4].class
|
88
|
+
|
89
|
+
photos = Photo.all
|
90
|
+
|
91
|
+
assert_equal 2, photos.size
|
92
|
+
assert_equal 'photo2', photos[1].title
|
93
|
+
assert_equal 'http:/www.gmosx.com/photo/1', photos[0].url
|
94
|
+
|
95
|
+
articles = Article.all
|
96
|
+
|
97
|
+
assert_equal 3, articles.size
|
98
|
+
assert_equal 'art3', articles[2].title
|
99
|
+
|
100
|
+
articles = Article.all(:limit => 2)
|
101
|
+
assert_equal 2, articles.size
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), 'lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
require 'og'
|
6
|
+
|
7
|
+
class TC_OgPolymorphic < Test::Unit::TestCase # :nodoc: all
|
8
|
+
include Og
|
9
|
+
|
10
|
+
# This class is a polymorphic parent. Ie' it acts as template
|
11
|
+
# to generate customized versions of this class.
|
12
|
+
|
13
|
+
class Comment
|
14
|
+
property :body, String
|
15
|
+
belongs_to :parent, Object # polymorphic marker !
|
16
|
+
|
17
|
+
def initialize(body)
|
18
|
+
@body = body
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Article
|
23
|
+
property :title, String
|
24
|
+
has_many Comment
|
25
|
+
|
26
|
+
def initialize(title)
|
27
|
+
@title = title
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class User
|
32
|
+
property :name, String
|
33
|
+
has_many Comment
|
34
|
+
|
35
|
+
def initialize(name)
|
36
|
+
@name = name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def setup
|
41
|
+
@og = Og.setup(
|
42
|
+
:destroy => true,
|
43
|
+
:store => :sqlite,
|
44
|
+
:name => 'test'
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_all
|
49
|
+
u = User.create('gmosx')
|
50
|
+
|
51
|
+
u.comments << User::Comment.create('Hello')
|
52
|
+
u.comments << User::Comment.create('World')
|
53
|
+
|
54
|
+
assert_equal 2, u.comments.size
|
55
|
+
|
56
|
+
a = Article.create('test')
|
57
|
+
|
58
|
+
a.comments << Article::Comment.create('Hello2')
|
59
|
+
a.comments << Article::Comment.create('World2')
|
60
|
+
|
61
|
+
assert_equal 2, a.comments.size
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
data/test/og/tc_store.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
$:.unshift File.join(File.dirname(__FILE__), 'lib')
|
2
2
|
|
3
|
-
|
3
|
+
$DBG = true
|
4
4
|
|
5
5
|
require 'test/unit'
|
6
6
|
|
@@ -77,7 +77,7 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
77
77
|
# conversions_test
|
78
78
|
end
|
79
79
|
=end
|
80
|
-
|
80
|
+
=begin
|
81
81
|
def test_psql
|
82
82
|
@og = Og.setup(
|
83
83
|
:destroy => true,
|
@@ -90,7 +90,7 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
90
90
|
features_test
|
91
91
|
conversions_test
|
92
92
|
end
|
93
|
-
|
93
|
+
=end
|
94
94
|
=begin
|
95
95
|
def test_mysql
|
96
96
|
@og = Og.setup(
|
@@ -98,13 +98,14 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
98
98
|
:store => :mysql,
|
99
99
|
:name => 'test',
|
100
100
|
:user => 'root',
|
101
|
+
:table_type => 'InnoDB',
|
101
102
|
:password => 'navelrulez'
|
102
103
|
)
|
103
104
|
features_test
|
104
105
|
# conversions_test
|
105
106
|
end
|
106
107
|
=end
|
107
|
-
|
108
|
+
#=begin
|
108
109
|
def test_sqlite
|
109
110
|
@og = Og.setup(
|
110
111
|
:destroy => true,
|
@@ -114,7 +115,7 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
114
115
|
features_test
|
115
116
|
conversions_test
|
116
117
|
end
|
117
|
-
|
118
|
+
#=end
|
118
119
|
=begin
|
119
120
|
def test_memory
|
120
121
|
@og = Og.setup(
|
@@ -136,6 +137,39 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
136
137
|
|
137
138
|
assert_equal a1.body, a2.body
|
138
139
|
|
140
|
+
# custom select.
|
141
|
+
|
142
|
+
acs = Article.select("SELECT * FROM #{Article.table} WHERE oid=1")
|
143
|
+
assert_equal 'Article 1', acs.first.body
|
144
|
+
|
145
|
+
acs = Article.select_one("SELECT * FROM #{Article.table} WHERE oid=1")
|
146
|
+
assert_equal 'Article 1', acs.body
|
147
|
+
|
148
|
+
acs = Article.select_one("WHERE oid=1")
|
149
|
+
assert_equal 'Article 1', acs.body
|
150
|
+
|
151
|
+
acs = Article.find(:sql => "SELECT * FROM #{Article.table} WHERE oid=1")
|
152
|
+
assert_equal 'Article 1', acs.first.body
|
153
|
+
|
154
|
+
# prefered way?
|
155
|
+
|
156
|
+
acs = Article.find(:sql => "WHERE oid=1")
|
157
|
+
assert_equal 'Article 1', acs.first.body
|
158
|
+
|
159
|
+
# exist?
|
160
|
+
|
161
|
+
assert Article.exist?(1)
|
162
|
+
assert_equal nil, Article.exist?(999)
|
163
|
+
|
164
|
+
# update
|
165
|
+
|
166
|
+
a = Article[1]
|
167
|
+
a.body = 'Changed'
|
168
|
+
# test affected rows.
|
169
|
+
assert_equal 1, a.save
|
170
|
+
|
171
|
+
#
|
172
|
+
|
139
173
|
a3 = Article.create do |a|
|
140
174
|
a.title = 'Title 3'
|
141
175
|
a.body = 'Article 3'
|
@@ -177,7 +211,7 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
177
211
|
|
178
212
|
c1.reload
|
179
213
|
assert_equal 'Comment 4', c1.body
|
180
|
-
|
214
|
+
|
181
215
|
# count
|
182
216
|
|
183
217
|
assert_equal 4, @og.store.count(:class => Comment)
|
@@ -187,7 +221,7 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
187
221
|
|
188
222
|
# update_properties
|
189
223
|
|
190
|
-
Comment.update_properties('@hits = @hits + 1')
|
224
|
+
assert_equal 4, Comment.update_properties('@hits = @hits + 1')
|
191
225
|
cc = Comment[1]
|
192
226
|
assert_equal 1, cc.hits
|
193
227
|
Comment.update_properties('@hits = @hits + 1', :condition => 'oid = 1')
|
@@ -199,15 +233,15 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
199
233
|
|
200
234
|
# update selected properties.
|
201
235
|
|
202
|
-
cc.hits = 5
|
203
|
-
cc.update
|
236
|
+
cc.hits = 5
|
237
|
+
cc.update :only => :hits
|
204
238
|
assert_equal 5, cc.hits
|
205
239
|
cc.reload
|
206
240
|
assert_equal 5, cc.hits
|
207
241
|
|
208
242
|
cc.hits += 1
|
209
243
|
cc.body = 'Wow!'
|
210
|
-
cc.update
|
244
|
+
cc.update :only => [:hits, :body]
|
211
245
|
cc.reload
|
212
246
|
assert_equal 'Wow!', cc.body
|
213
247
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
|
|
3
3
|
specification_version: 1
|
4
4
|
name: og
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2005-06-
|
6
|
+
version: 0.19.0
|
7
|
+
date: 2005-06-17
|
8
8
|
summary: Og (ObjectGraph)
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -69,11 +69,11 @@ files:
|
|
69
69
|
- lib/og/mixin/orderable.rb
|
70
70
|
- lib/og/mixin/timestamped.rb
|
71
71
|
- lib/og/mixin/tree.rb
|
72
|
+
- lib/og/mixin/optimistic_locking.rb
|
72
73
|
- lib/og/store/filesys.rb
|
73
74
|
- lib/og/store/psql.rb
|
74
75
|
- lib/og/store/sql.rb
|
75
76
|
- lib/og/store/mysql.rb
|
76
|
-
- lib/og/store/madeleine.rb
|
77
77
|
- lib/og/store/sqlserver.rb
|
78
78
|
- lib/og/store/sqlite.rb
|
79
79
|
- lib/og/store/kirby.rb
|
@@ -85,13 +85,16 @@ files:
|
|
85
85
|
- test/og
|
86
86
|
- test/og/store
|
87
87
|
- test/og/mixin
|
88
|
+
- test/og/tc_inheritance.rb
|
88
89
|
- test/og/tc_types.rb
|
89
90
|
- test/og/tc_relation.rb
|
90
91
|
- test/og/tc_store.rb
|
92
|
+
- test/og/tc_polymorphic.rb
|
91
93
|
- test/og/store/tc_filesys.rb
|
92
94
|
- test/og/mixin/tc_hierarchical.rb
|
93
95
|
- test/og/mixin/tc_orderable.rb
|
94
96
|
- test/og/mixin/tc_timestamped.rb
|
97
|
+
- test/og/mixin/tc_optimistic_locking.rb
|
95
98
|
test_files: []
|
96
99
|
rdoc_options:
|
97
100
|
- "--main"
|
@@ -117,7 +120,7 @@ dependencies:
|
|
117
120
|
-
|
118
121
|
- "="
|
119
122
|
- !ruby/object:Gem::Version
|
120
|
-
version: 0.
|
123
|
+
version: 0.19.0
|
121
124
|
version:
|
122
125
|
- !ruby/object:Gem::Dependency
|
123
126
|
name: facets
|