og 0.29.0 → 0.30.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,12 +2,12 @@
2
2
 
3
3
  TITLE : &title Og
4
4
  NAME : &pkg og
5
- VERSION : '0.29.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.nitrohq.com"
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
- RDOC:
29
- - dir: rdoc
30
- options: ['--all', '--inline-source']
31
- include:
32
- - 'lib/og/**/*'
33
- - '[A-Z]*'
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
- # Anything to require upfront?
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.nitrohq.com
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.29.0 README
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.nitrohq.com).
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.nitrohq.com
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.nitrohq.com
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.nitrohq.com)
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.nitrohq.com) is copyrighted free
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.
@@ -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
 
@@ -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
@@ -1,6 +1,5 @@
1
- require 'facet/ormsupport'
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
- # include Hierarchical, :method => :nested_sets
121
+ # is Hierarchical, :method => :nested_sets
123
122
  # end
124
123
  #
125
124
  # [+:method+]
@@ -1,4 +1,4 @@
1
- require 'glue/on_included'
1
+ require 'facets/core/module/on_included'
2
2
 
3
3
  module Glue
4
4
 
@@ -1,12 +1,12 @@
1
- require 'glue/paramix'
2
- require 'glue/aspects'
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 Glue::Aspects
9
+ include ::Aspects
10
10
 
11
11
  def self.included_with_parameters(base, opt)
12
12
  base.module_eval do
@@ -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
- info = ogmanager.store.join_table_info(self, Tag)
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 t.*
178
- FROM
179
- #{info[:first_table]} AS o,
180
- #{info[:second_table]} as t,
181
- #{info[:table]} as j
182
- WHERE o.oid = j.#{info[:first_key]}
183
- AND t.oid = j.#{info[:second_key]}
184
- AND (o.name in (#{names}))
185
- GROUP BY j.article_oid
186
- HAVING COUNT(j.article_oid) = #{count};
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
- info = ogmanager.store.join_table_info(self, Tag)
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 t.*
201
- FROM
202
- #{info[:first_table]} AS o,
203
- #{info[:second_table]} as t,
204
- #{info[:table]} as j
205
- WHERE
206
- o.oid = j.#{info[:first_key]}
207
- AND t.oid = j.#{info[:second_key]}
208
- AND (o.name in (#{names}))
209
- GROUP BY j.article_oid
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, Glue::Aspects
226
+ base.send :include, ::Aspects
224
227
  base.before 'tags.clear', :on => [:og_delete]
225
228
  end
226
229
 
@@ -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 Glue::Aspects
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 Glue::Aspects
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-2005, George Moschovitis (http://www.gmosx.com)
4
- # Copyright (c) 2004-2005, Navel Ltd (http://www.navel.gr)
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.nitrohq.com) is copyrighted free software
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.29.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
- # change thread_safe mode
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
@@ -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 sqll query.
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