og 0.29.0 → 0.30.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ProjectInfo +17 -28
- data/README +6 -6
- data/doc/AUTHORS +6 -0
- data/doc/RELEASES +36 -0
- data/lib/glue/hierarchical.rb +3 -4
- data/lib/glue/optimistic_locking.rb +1 -1
- data/lib/glue/orderable.rb +3 -3
- data/lib/glue/taggable.rb +29 -26
- data/lib/glue/timestamped.rb +3 -4
- data/lib/og.rb +21 -9
- data/lib/og/entity.rb +44 -2
- data/lib/og/manager.rb +9 -6
- data/lib/og/markers.rb +9 -1
- data/lib/og/relation.rb +9 -5
- data/lib/og/relation/joins_many.rb +2 -2
- data/lib/og/store/alpha/memory.rb +8 -8
- data/lib/og/store/alpha/sqlserver.rb +3 -3
- data/lib/og/store/kirby.rb +422 -279
- data/lib/og/store/mysql.rb +33 -24
- data/lib/og/store/psql.rb +28 -18
- data/lib/og/store/sql.rb +99 -33
- data/lib/og/store/sqlite.rb +13 -7
- data/lib/og/store/sqlite2.rb +14 -4
- data/test/og/CONFIG.rb +2 -2
- data/test/og/store/tc_sti.rb +41 -0
- data/test/og/tc_aggregations_calculations.rb +8 -2
- data/test/og/tc_cacheable.rb +6 -2
- data/test/og/tc_camel_case_join.rb +51 -0
- data/test/og/tc_ez.rb +30 -1
- data/test/og/tc_join.rb +73 -6
- data/test/og/tc_multi_validations.rb +1 -1
- metadata +53 -53
- data/Rakefile +0 -220
data/ProjectInfo
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
TITLE : &title Og
|
4
4
|
NAME : &pkg og
|
5
|
-
VERSION : '0.
|
5
|
+
VERSION : '0.30.0'
|
6
6
|
STATUS : beta
|
7
7
|
|
8
8
|
AUTHOR : George Moschovitis
|
9
9
|
EMAIL : &email gm@navel.gr
|
10
|
-
HOMEPAGE : "http://www.
|
10
|
+
HOMEPAGE : "http://www.nitroproject.org"
|
11
11
|
|
12
12
|
SUMMARY: State of the art object-relational mapping system.
|
13
13
|
|
@@ -16,27 +16,26 @@ DESCRIPTION: >
|
|
16
16
|
Og serializes standard Ruby objects to Mysql, Postgres, Sqlite,
|
17
17
|
KirbyBase, Filesystem and more.
|
18
18
|
|
19
|
-
DEPENDENCIES:
|
20
|
-
- [ glue, '= 0.29.0' ]
|
21
|
-
|
22
|
-
DISTRIBUTE: [ gem, tgz, zip ]
|
23
|
-
|
24
19
|
RUBYFORGE:
|
25
20
|
PROJECT: 'nitro'
|
26
21
|
USERNAME: 'gmosx'
|
27
22
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
23
|
+
DEPENDENCIES:
|
24
|
+
- [ glue, '= 0.30.0' ]
|
25
|
+
|
26
|
+
PACKAGE: !!package
|
27
|
+
distribute: [ gem, tgz, zip ]
|
28
|
+
|
29
|
+
RDOC: !!rdoc
|
30
|
+
dir: rdoc
|
31
|
+
options: ['--all', '--inline-source']
|
32
|
+
include:
|
33
|
+
- 'lib/og/**/*'
|
34
|
+
- '[A-Z]*'
|
34
35
|
|
35
|
-
|
36
|
-
#TEST:
|
37
|
-
# fixture: ''
|
36
|
+
TEST: !!test
|
38
37
|
|
39
|
-
ANNOUNCE:
|
38
|
+
ANNOUNCE: !!announce
|
40
39
|
to: george.moschovitis@gmail.com
|
41
40
|
from: gm@navel.gr
|
42
41
|
domain: navel.gr
|
@@ -48,15 +47,5 @@ ANNOUNCE:
|
|
48
47
|
file: ANN
|
49
48
|
slogan: Og (ObjectGraph)
|
50
49
|
links:
|
51
|
-
- http://www.
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
50
|
+
- http://www.nitroproject.org
|
62
51
|
|
data/README
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Og 0.
|
1
|
+
= Og 0.30.0 README
|
2
2
|
|
3
3
|
Og (ObjectGraph) is a powerful and elegant object-relational mapping
|
4
4
|
library. Og manages the lifecycle of Ruby objects and provides
|
@@ -21,7 +21,7 @@ Filesystem, Oracle and SQL Server are included.
|
|
21
21
|
|
22
22
|
Og is part of the Nitro project, released as a stand-alone library
|
23
23
|
due to popular demand. You can find the ChangeLog in the Nitro
|
24
|
-
distribution (http://www.
|
24
|
+
distribution (http://www.nitroproject.org).
|
25
25
|
|
26
26
|
|
27
27
|
== Features
|
@@ -73,19 +73,19 @@ doc/RELEASES
|
|
73
73
|
|
74
74
|
The latest version of Og can be found at
|
75
75
|
|
76
|
-
* http://www.
|
76
|
+
* http://www.nitroproject.org
|
77
77
|
|
78
78
|
== Documentation
|
79
79
|
|
80
80
|
Documentation for Og can be found at
|
81
81
|
|
82
|
-
* http://www.
|
82
|
+
* http://www.nitroproject.org
|
83
83
|
|
84
84
|
Don't forget to read the file doc/RELEASES for usefull
|
85
85
|
documentation bits. Also, have a look at the test cases in
|
86
86
|
the test directory for examples of usage. Additional examples
|
87
87
|
of Og usage can be found at the example distribution of the
|
88
|
-
Nitro Web Framework (http://www.
|
88
|
+
Nitro Web Framework (http://www.nitroproject.org)
|
89
89
|
|
90
90
|
You can find a nice tutorial at www.rubygarden.com. Be warned
|
91
91
|
that this tutorial describes an earlier version of Og. A *LOT*
|
@@ -170,7 +170,7 @@ http://rubyforge.org/mailman/listinfo/nitro-general
|
|
170
170
|
Copyright (c) 2004-2006, George 'gmosx' Moschovitis (http://www.gmosx.com).
|
171
171
|
Copyright (c) 2004-2006, Navel Ltd (http://www.navel.gr)
|
172
172
|
|
173
|
-
Og (http://www.
|
173
|
+
Og (http://www.nitroproject.org) is copyrighted free
|
174
174
|
software created and maintained by George Moschovitis (mailto:gm@navel.gr)
|
175
175
|
and released under the standard BSD Licence. For details consult
|
176
176
|
the file LICENCE.
|
data/doc/AUTHORS
CHANGED
@@ -30,6 +30,12 @@ IDEAS, ADDITIONAL CODING, SUPPORT:
|
|
30
30
|
* Ghislain Mary <gmary@lunacymaze.org>
|
31
31
|
Bug reports and patches (sqlite3 driver).
|
32
32
|
|
33
|
+
* Kashia Buch <kashia@vfemail.net>
|
34
|
+
Patches.
|
35
|
+
|
36
|
+
* Dylan Bruzenak <dylanb@digitalvalence.com>
|
37
|
+
Patches (kirby).
|
38
|
+
|
33
39
|
* Matt Bowen <matt.bowen@farweststeel.com>
|
34
40
|
Oracle driver, documentation.
|
35
41
|
|
data/doc/RELEASES
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
== Version 0.30.0
|
2
|
+
|
3
|
+
Another pragmatic release. The Nitro development team worked over
|
4
|
+
the submitted tickets and provided many bug fixes. More over, there
|
5
|
+
are many small improvements along the codebase and as always
|
6
|
+
we could not resist adding some cool new features.
|
7
|
+
|
8
|
+
Special thanks fly to Bryan Sotto for making this release
|
9
|
+
possible!
|
10
|
+
|
11
|
+
Most notable chages:
|
12
|
+
|
13
|
+
* Added Og query by example support. Query the database for an
|
14
|
+
entity that matches the example. The example is a hash
|
15
|
+
populated with the property values to search for.
|
16
|
+
|
17
|
+
The provided property values are joined with AND to build
|
18
|
+
the actual query.
|
19
|
+
|
20
|
+
Article.query_by_example :title => 'IBM%', :hits => 2
|
21
|
+
Article.find_with_properties :title => 'IBM%', :hits => 2
|
22
|
+
|
23
|
+
* Added type casting support for Og aggregations and
|
24
|
+
calculations.
|
25
|
+
|
26
|
+
* Added many more RDoc comments to the source code.
|
27
|
+
|
28
|
+
* Many, many bug fixes.
|
29
|
+
|
30
|
+
* Updated to latest Facets.
|
31
|
+
|
32
|
+
Please note that the project home page has been moved to:
|
33
|
+
|
34
|
+
http://www.nitroproject.org
|
35
|
+
|
36
|
+
|
1
37
|
== Version 0.29.0
|
2
38
|
|
3
39
|
A bold step towards maturity. Great care was taken to
|
data/lib/glue/hierarchical.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require 'glue/paramix'
|
1
|
+
require 'facets/more/paramix'
|
2
|
+
require 'facets/more/ormsupport'
|
4
3
|
|
5
4
|
module Glue
|
6
5
|
|
@@ -119,7 +118,7 @@ end
|
|
119
118
|
# === Example
|
120
119
|
#
|
121
120
|
# class Comment
|
122
|
-
#
|
121
|
+
# is Hierarchical, :method => :nested_sets
|
123
122
|
# end
|
124
123
|
#
|
125
124
|
# [+:method+]
|
data/lib/glue/orderable.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'facets/more/paramix'
|
2
|
+
require 'facets/more/aspects'
|
3
3
|
|
4
4
|
module Glue
|
5
5
|
|
6
6
|
# Attach list/ordering methods to the enchanted class.
|
7
7
|
|
8
8
|
module Orderable
|
9
|
-
include
|
9
|
+
include ::Aspects
|
10
10
|
|
11
11
|
def self.included_with_parameters(base, opt)
|
12
12
|
base.module_eval do
|
data/lib/glue/taggable.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'facet/inflect'
|
2
2
|
|
3
|
-
module Glue
|
4
|
-
|
5
3
|
# The default Tag implementation. A tag attaches semantics to
|
6
4
|
# a given object.
|
7
5
|
#--
|
@@ -83,6 +81,8 @@ class Tag
|
|
83
81
|
end
|
84
82
|
end
|
85
83
|
|
84
|
+
module Glue
|
85
|
+
|
86
86
|
# Add tagging methods to the target class.
|
87
87
|
# For more information on the algorithms used surf:
|
88
88
|
# http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html
|
@@ -170,20 +170,22 @@ module Taggable
|
|
170
170
|
# INTERSECTION (AND)
|
171
171
|
|
172
172
|
def find_with_tags(*names)
|
173
|
-
|
173
|
+
relation = relations.reject{|r| r.name != :tags}.first
|
174
|
+
info = ogmanager.store.join_table_info(relation)
|
174
175
|
count = names.size
|
175
176
|
names = names.map { |n| ogmanager.store.quote(n) }.join(',')
|
176
|
-
sql = %{
|
177
|
-
SELECT
|
178
|
-
FROM
|
179
|
-
|
180
|
-
|
181
|
-
#{info[:
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
177
|
+
sql = %{
|
178
|
+
SELECT *
|
179
|
+
FROM #{info[:owner_table]} AS o
|
180
|
+
WHERE o.oid IN (
|
181
|
+
SELECT j.#{info[:owner_key]}
|
182
|
+
FROM #{info[:target_table]} AS t
|
183
|
+
JOIN #{info[:table]} AS j
|
184
|
+
ON t.oid = j.#{info[:target_key]}
|
185
|
+
WHERE (t.name IN (#{names}))
|
186
|
+
GROUP BY j.#{info[:owner_key]}
|
187
|
+
HAVING COUNT(j.#{info[:owner_key]}) = #{count}
|
188
|
+
)
|
187
189
|
}
|
188
190
|
return self.select(sql)
|
189
191
|
end
|
@@ -193,20 +195,21 @@ module Taggable
|
|
193
195
|
# UNION (OR)
|
194
196
|
|
195
197
|
def find_with_any_tag(*names)
|
196
|
-
|
198
|
+
relation = relations.reject{|r| r.name != :tags}.first
|
199
|
+
info = ogmanager.store.join_table_info(relation)
|
197
200
|
count = names.size
|
198
201
|
names = names.map { |n| ogmanager.store.quote(n) }.join(',')
|
199
202
|
sql = %{
|
200
|
-
SELECT
|
201
|
-
FROM
|
202
|
-
|
203
|
-
|
204
|
-
#{info[:
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
203
|
+
SELECT *
|
204
|
+
FROM #{info[:owner_table]} AS o
|
205
|
+
WHERE o.oid IN (
|
206
|
+
SELECT j.#{info[:owner_key]}
|
207
|
+
FROM #{info[:target_table]} AS t
|
208
|
+
JOIN #{info[:table]} AS j
|
209
|
+
ON t.oid = j.#{info[:target_key]}
|
210
|
+
WHERE (t.name IN (#{names}))
|
211
|
+
GROUP BY j.#{info[:owner_key]}
|
212
|
+
)
|
210
213
|
}
|
211
214
|
return self.select(sql)
|
212
215
|
end
|
@@ -220,7 +223,7 @@ module Taggable
|
|
220
223
|
#--
|
221
224
|
# FIXME: Og should handle this automatically.
|
222
225
|
#++
|
223
|
-
base.send :include,
|
226
|
+
base.send :include, ::Aspects
|
224
227
|
base.before 'tags.clear', :on => [:og_delete]
|
225
228
|
end
|
226
229
|
|
data/lib/glue/timestamped.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
require 'facet/time/stamp'
|
2
|
-
|
3
|
-
require 'glue/aspects'
|
2
|
+
require 'facets/more/aspects'
|
4
3
|
|
5
4
|
module Glue
|
6
5
|
|
7
6
|
# Adds timestamping functionality.
|
8
7
|
|
9
8
|
module Timestamped
|
10
|
-
include
|
9
|
+
include ::Aspects
|
11
10
|
|
12
11
|
property :create_time, Time, :control => :none
|
13
12
|
property :update_time, Time, :control => :none
|
@@ -27,7 +26,7 @@ end
|
|
27
26
|
# module.
|
28
27
|
|
29
28
|
module TimestampedOnCreate
|
30
|
-
include
|
29
|
+
include ::Aspects
|
31
30
|
property :create_time, Time, :control => :none
|
32
31
|
before "@create_time = Time.now", :on => :og_insert
|
33
32
|
end
|
data/lib/og.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
# = Og
|
2
2
|
#
|
3
|
-
# Copyright (c) 2004-
|
4
|
-
# Copyright (c) 2004-
|
3
|
+
# Copyright (c) 2004-2006, George Moschovitis (http://www.gmosx.com)
|
4
|
+
# Copyright (c) 2004-2006, Navel Ltd (http://www.navel.gr)
|
5
5
|
#
|
6
|
-
# Og (http://www.
|
6
|
+
# Og (http://www.nitroproject.org) is copyrighted free software
|
7
7
|
# created and maintained by George Moschovitis (mailto:gm@navel.gr)
|
8
8
|
# and released under the standard BSD Licence. For details
|
9
9
|
# consult the file doc/LICENCE.
|
10
10
|
|
11
11
|
require 'facet/synchash'
|
12
12
|
require 'facet/syncarray'
|
13
|
+
require 'facets/more/aspects'
|
13
14
|
|
14
15
|
require 'glue'
|
15
16
|
require 'glue/logger'
|
16
17
|
require 'glue/validation'
|
17
|
-
require 'glue/aspects'
|
18
18
|
require 'glue/configuration'
|
19
19
|
|
20
20
|
# Og (ObjectGraph) manages Ruby objects and their relations and
|
@@ -43,7 +43,7 @@ module Og
|
|
43
43
|
|
44
44
|
# The version.
|
45
45
|
|
46
|
-
Version = '0.
|
46
|
+
Version = '0.30.0'
|
47
47
|
|
48
48
|
# Library path.
|
49
49
|
|
@@ -92,8 +92,7 @@ module Og
|
|
92
92
|
setting :raise_store_exceptions, :default => true, :doc => 'If true raises exceptions on store errors'
|
93
93
|
|
94
94
|
# Enable/dissable thread safe mode.
|
95
|
-
|
96
|
-
#setting :thread_safe, :default => true, :doc => 'Enable/dissable thread safe mode'
|
95
|
+
# setting :thread_safe, :default => true, :doc => 'Enable/dissable thread safe mode'
|
97
96
|
|
98
97
|
# Address of the Og cache (if distributed caching enabled).
|
99
98
|
|
@@ -103,6 +102,11 @@ module Og
|
|
103
102
|
|
104
103
|
setting :cache_port, :default => '9070', :doc => 'Port of the Og cache'
|
105
104
|
|
105
|
+
# A collection of classes that are unmanageable, ie the manager
|
106
|
+
# should ignore them.
|
107
|
+
|
108
|
+
setting :unmanageable_classes, :default => [], :doc => 'Explicitly unmanageable classes'
|
109
|
+
|
106
110
|
# The active manager
|
107
111
|
|
108
112
|
mattr_accessor :manager
|
@@ -154,6 +158,7 @@ module Og
|
|
154
158
|
end
|
155
159
|
alias_method :connect, :setup
|
156
160
|
alias_method :options=, :setup
|
161
|
+
alias_method :setup=, :setup
|
157
162
|
alias_method :start, :setup
|
158
163
|
|
159
164
|
# Helper method.
|
@@ -162,10 +167,17 @@ module Og
|
|
162
167
|
@@manager.store.escape(str)
|
163
168
|
end
|
164
169
|
|
165
|
-
#
|
170
|
+
# Quote the string.
|
171
|
+
|
172
|
+
def quote(str)
|
173
|
+
@@manager.store.quote(str)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Change thread_safe mode.
|
177
|
+
|
166
178
|
def thread_safe=(bool)
|
167
179
|
@@thread_safe = bool
|
168
|
-
@@manager and @@manager.class.managers.each { |m| m.initialize_store }
|
180
|
+
# @@manager and @@manager.class.managers.each { |m| m.initialize_store }
|
169
181
|
@@thread_safe
|
170
182
|
end
|
171
183
|
end
|
data/lib/og/entity.rb
CHANGED
@@ -38,7 +38,7 @@ module EntityMixin
|
|
38
38
|
# don't pass.
|
39
39
|
|
40
40
|
def force_save!(options = nil)
|
41
|
-
self.class.ogmanager.store.force_save(self, options)
|
41
|
+
self.class.ogmanager.store.force_save!(self, options)
|
42
42
|
end
|
43
43
|
|
44
44
|
# Insert the object in the store.
|
@@ -158,6 +158,8 @@ module EntityMixin
|
|
158
158
|
ogmanager.store.update_by_sql(self, set, options)
|
159
159
|
end
|
160
160
|
|
161
|
+
# :section: Query methods.
|
162
|
+
|
161
163
|
# Find a specific instance of this class according
|
162
164
|
# to the given conditions.
|
163
165
|
#
|
@@ -215,11 +217,46 @@ module EntityMixin
|
|
215
217
|
ogmanager.store.select(sql, self)
|
216
218
|
end
|
217
219
|
|
218
|
-
# Select one instance using an
|
220
|
+
# Select one instance using an sql query.
|
219
221
|
|
220
222
|
def select_one(sql)
|
221
223
|
ogmanager.store.select_one(sql, self)
|
222
224
|
end
|
225
|
+
|
226
|
+
# Query the database for an entity that matches the example.
|
227
|
+
# The example is a hash populated with the property values
|
228
|
+
# to search for.
|
229
|
+
#
|
230
|
+
# The provided property values are joined with AND to build
|
231
|
+
# the actual query.
|
232
|
+
#
|
233
|
+
# Article.query_by_example :title => 'IBM%', :hits => 2
|
234
|
+
# Article.find_with_properties :title => 'IBM%', :hits => 2
|
235
|
+
|
236
|
+
def query_by_example(example)
|
237
|
+
condition = []
|
238
|
+
example.each do |k, v|
|
239
|
+
next if v.nil?
|
240
|
+
if v.is_a? String and v =~ /%/
|
241
|
+
condition << "#{k} LIKE #{Og.quote(v)}"
|
242
|
+
else
|
243
|
+
condition << "#{k} = #{Og.quote(v)}"
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
condition = condition.join(' AND ')
|
248
|
+
|
249
|
+
options = {
|
250
|
+
:condition => condition,
|
251
|
+
:class => self,
|
252
|
+
}
|
253
|
+
|
254
|
+
options[:type] = self if self.schema_inheritance_child?
|
255
|
+
|
256
|
+
ogmanager.store.find(options)
|
257
|
+
end
|
258
|
+
alias_method :qbe, :query_by_example
|
259
|
+
alias_method :find_with_properties, :query_by_example
|
223
260
|
|
224
261
|
# :section: Aggregations / Calculations
|
225
262
|
|
@@ -234,6 +271,7 @@ module EntityMixin
|
|
234
271
|
# Perform a count query.
|
235
272
|
|
236
273
|
def count(options = {})
|
274
|
+
options[:field] = '*'
|
237
275
|
calculate('COUNT(*)', options).to_i
|
238
276
|
end
|
239
277
|
|
@@ -241,6 +279,7 @@ module EntityMixin
|
|
241
279
|
# Pass a :group option to return an aggregation.
|
242
280
|
|
243
281
|
def minimum(min, options = {})
|
282
|
+
options[:field] = min
|
244
283
|
calculate("MIN(#{min})", options)
|
245
284
|
end
|
246
285
|
alias_method :min, :minimum
|
@@ -249,6 +288,7 @@ module EntityMixin
|
|
249
288
|
# Pass a :group option to return an aggregation.
|
250
289
|
|
251
290
|
def maximum(max, options = {})
|
291
|
+
options[:field] = max
|
252
292
|
calculate("MAX(#{max})", options)
|
253
293
|
end
|
254
294
|
alias_method :max, :maximum
|
@@ -257,6 +297,7 @@ module EntityMixin
|
|
257
297
|
# Pass a :group option to return an aggregation.
|
258
298
|
|
259
299
|
def average(avg, options = {})
|
300
|
+
options[:field] = avg
|
260
301
|
calculate("AVG(#{avg})", options)
|
261
302
|
end
|
262
303
|
alias_method :avg, :average
|
@@ -265,6 +306,7 @@ module EntityMixin
|
|
265
306
|
# Pass a :group option to return an aggregation.
|
266
307
|
|
267
308
|
def summarize(sum, options = {})
|
309
|
+
options[:field] = sum
|
268
310
|
calculate("SUM(#{sum})", options)
|
269
311
|
end
|
270
312
|
alias_method :sum, :summarize
|