og 0.27.0 → 0.28.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.
Files changed (61) hide show
  1. data/ProjectInfo +2 -2
  2. data/README +8 -4
  3. data/Rakefile +1 -1
  4. data/doc/AUTHORS +1 -1
  5. data/doc/RELEASES +81 -0
  6. data/examples/README +7 -0
  7. data/lib/glue/cacheable.rb +152 -0
  8. data/lib/glue/hierarchical.rb +5 -4
  9. data/lib/glue/optimistic_locking.rb +0 -1
  10. data/lib/glue/orderable.rb +46 -44
  11. data/lib/glue/taggable.rb +7 -4
  12. data/lib/glue/timestamped.rb +1 -1
  13. data/lib/og.rb +13 -6
  14. data/lib/og/entity.rb +226 -9
  15. data/lib/og/evolution.rb +2 -2
  16. data/lib/og/ez/clause.rb +147 -0
  17. data/lib/og/ez/condition.rb +181 -0
  18. data/lib/og/manager.rb +31 -30
  19. data/lib/og/relation.rb +5 -5
  20. data/lib/og/relation/has_many.rb +3 -1
  21. data/lib/og/relation/joins_many.rb +1 -1
  22. data/lib/og/store.rb +6 -3
  23. data/lib/og/store/kirby.rb +3 -5
  24. data/lib/og/store/mysql.rb +0 -1
  25. data/lib/og/store/sql.rb +43 -7
  26. data/lib/og/store/sqlite.rb +97 -11
  27. data/lib/og/store/sqlite2.rb +231 -0
  28. data/lib/og/test/testcase.rb +1 -1
  29. data/lib/og/vendor/mysql.rb +103 -25
  30. data/test/glue/tc_revisable.rb +11 -11
  31. data/test/og/CONFIG.rb +20 -8
  32. data/test/og/mixin/tc_hierarchical.rb +5 -3
  33. data/test/og/mixin/tc_optimistic_locking.rb +6 -4
  34. data/test/og/mixin/tc_orderable.rb +22 -22
  35. data/test/og/mixin/tc_taggable.rb +15 -11
  36. data/test/og/mixin/tc_timestamped.rb +4 -2
  37. data/test/og/multi_validations_model.rb +8 -0
  38. data/test/og/store/tc_filesys.rb +15 -12
  39. data/test/og/store/tc_kirby.rb +14 -11
  40. data/test/og/tc_accumulator.rb +1 -3
  41. data/test/og/tc_cacheable.rb +58 -0
  42. data/test/og/tc_delete_all.rb +13 -16
  43. data/test/og/tc_ez.rb +33 -0
  44. data/test/og/tc_finder.rb +2 -4
  45. data/test/og/tc_inheritance.rb +3 -3
  46. data/test/og/tc_inheritance2.rb +2 -3
  47. data/test/og/tc_join.rb +3 -2
  48. data/test/og/tc_multi_validations.rb +3 -3
  49. data/test/og/tc_multiple.rb +3 -6
  50. data/test/og/tc_override.rb +19 -13
  51. data/test/og/tc_polymorphic.rb +1 -3
  52. data/test/og/tc_resolve.rb +32 -0
  53. data/test/og/tc_reverse.rb +27 -28
  54. data/test/og/tc_scoped.rb +2 -4
  55. data/test/og/tc_select.rb +1 -3
  56. data/test/og/tc_store.rb +3 -8
  57. data/test/og/tc_validation.rb +2 -2
  58. data/test/og/tc_validation2.rb +56 -58
  59. data/test/og/tc_validation_loop.rb +2 -5
  60. metadata +15 -7
  61. data/lib/og/vendor/mysql411.rb +0 -306
@@ -2,7 +2,7 @@
2
2
 
3
3
  TITLE : &title Og
4
4
  NAME : &pkg og
5
- VERSION : '0.27.0'
5
+ VERSION : '0.28.0'
6
6
  STATUS : beta
7
7
 
8
8
  AUTHOR : George Moschovitis
@@ -17,7 +17,7 @@ DESCRIPTION: >
17
17
  KirbyBase, Filesystem and more.
18
18
 
19
19
  DEPENDENCIES:
20
- - [ glue, '= 0.27.0' ]
20
+ - [ glue, '= 0.28.0' ]
21
21
 
22
22
  DISTRIBUTE: [ gem, tgz, zip ]
23
23
 
data/README CHANGED
@@ -1,4 +1,4 @@
1
- = Og 0.27.0 README
1
+ = Og 0.28.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
@@ -16,8 +16,8 @@ automatically generates join tables for many_to_many relations
16
16
  and provides a collection of usefull Mixins to synthesize
17
17
  common Entities.
18
18
 
19
- Adapters for PostgreSQL, MySQL, SQLite3, KirbyBase, Memory, Filesystem,
20
- Oracle and SQL Server are included.
19
+ Adapters for PostgreSQL, MySQL, SQLite3, KirbyBase, Memory,
20
+ 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
@@ -44,6 +44,8 @@ The library provides the following features:
44
44
  stores in the same application.
45
45
  * Deserialize to Ruby Objects.
46
46
  * Deserialize sql join queries to Ruby Objects.
47
+ * Can optionally use Ruby as a query language.
48
+ * Supports model caching (even on distribbuted environments)
47
49
  * Eager associations.
48
50
  * Serialize arbitrary ruby object graphs through YAML.
49
51
  * Connection pooling.
@@ -81,7 +83,9 @@ Documentation for Og can be found at
81
83
 
82
84
  Don't forget to read the file doc/RELEASES for usefull
83
85
  documentation bits. Also, have a look at the test cases in
84
- the test directory for examples of usage.
86
+ the test directory for examples of usage. Additional examples
87
+ of Og usage can be found at the example distribution of the
88
+ Nitro Web Framework (http://www.nitrohq.com)
85
89
 
86
90
  You can find a nice tutorial at www.rubygarden.com. Be warned
87
91
  that this tutorial describes an earlier version of Og. A *LOT*
data/Rakefile CHANGED
@@ -30,7 +30,7 @@ task :default => :package
30
30
  # Run the tests.
31
31
 
32
32
  Rake::TestTask.new do |t|
33
- cwd = File.expand_path(File.join(File.dirname(__FILE__) + '.'))
33
+ cwd = File.expand_path(File.join(File.dirname(__FILE__), '..'))
34
34
  t.libs << 'test'
35
35
  %w[glue nitro og].each do |dir|
36
36
  t.libs << File.join(cwd, dir, 'lib')
@@ -33,7 +33,7 @@ IDEAS, ADDITIONAL CODING, SUPPORT:
33
33
  * Matt Bowen <matt.bowen@farweststeel.com>
34
34
  Oracle driver, documentation.
35
35
 
36
- * Aidan Rogers <aidan@yoyo.org>
36
+ * Aidan Rogers <aidan@infurious.com>
37
37
  Bug reports, patches.
38
38
 
39
39
  * Thomas Quas <tquas@yahoo.com>
@@ -1,3 +1,84 @@
1
+ == Version 0.28.0
2
+
3
+ A snapshot of the latest developments. As always, cool new
4
+ features were added, the code is refactored, the security increased
5
+ and reported bugs fixed.
6
+
7
+ Most notable changes:
8
+
9
+ * New generalized caching system. The caching code is refactored
10
+ in a new Glue system. At the moment, caches in memory, DRb,
11
+ filesystem and Og are provided. A memcache version will be available
12
+ in the near future. The new caching system is used to implement
13
+ Session stores, Og caching, Fragment caching, and Application scoped
14
+ parameters. A useful DRb cache management script is provided to
15
+ manage multiple DRb caches.
16
+
17
+ * Introduced a new Og Cacheable mixin. By including this mixin
18
+ in your classes you make them eligible to Og caching. Here comes
19
+ an example:
20
+
21
+ class User
22
+ is Cachable
23
+ property :name, String
24
+ property :age, Fixnum
25
+ end
26
+
27
+ Cacheable reuses the new generalized caching system to provide
28
+ various options for distributed caching. At the moment entities
29
+ (instances of managed classes) are cached by their primary key.
30
+
31
+ * Og now advanced quering using Ruby as the data query language
32
+ to complement the usage of Ruby as a data definition language
33
+ and provide an end-to-end Ruby solution. At the moment only
34
+ supported for the SQL based adapters. Here comes an example:
35
+
36
+ users = User.find do |user|
37
+ user.age > 10
38
+ user.any {
39
+ name == 'George'
40
+ name == 'Stella'
41
+ }
42
+ end
43
+
44
+ # => SELECT * FROM oguser WHERE (oguser.age > 10 AND (oguser.name = 'George' OR oguser.name = 'Stella'))
45
+
46
+ This feature uses the Caboose/EZ code by Ezra. Pure magic!
47
+
48
+ * Og find now supports prepared statement like syntax:
49
+
50
+ User.find :condition => ['name LIKE ? and create_time > ?', 'g%', Time.now]
51
+
52
+ The interpolated values are automatically escaped to avoid
53
+ SQL injection attacks.
54
+
55
+ Some additional forms of find are supported:
56
+
57
+ User.find [['name = ? and create_time > ?', 'gmosx', Time.now]
58
+ User.find "name = 'gmosx'"
59
+
60
+ and more.
61
+
62
+ * Added experimental support for deep copying (cloning) of Og
63
+ managed objects. This mechanism handles properties (annotated
64
+ attributes) and some relation types.
65
+
66
+ * Integration of Facets 1.0.1. The new library features a better
67
+ API and better implementation of various features.
68
+
69
+ * Added schema evolution support to the SQLite adapter. All major
70
+ Og adapter support automatic schema evolution, ie Og detects common
71
+ types of changes in your Ruby code to automatically alter the
72
+ underlying schema for you.
73
+
74
+ * Introduced Og SQLite2 (legacy SQLite) adapter.
75
+
76
+ * Added more test cases, and improved RDoc comments throughout
77
+ the code.
78
+
79
+ * Many, many bug fixes.
80
+
81
+
1
82
  == Version 0.27.0
2
83
 
3
84
  Once again we have a great mix of cool new features, along
@@ -1,15 +1,22 @@
1
1
  = Og Examples
2
2
 
3
+ Here you can find some simple Og examples. For more examples
4
+ please download the Nitro examples tarball. Nitro is a Ruby
5
+ Web Framework that uses Og.
6
+
7
+
3
8
  == run.rb
4
9
 
5
10
  A simple example that demonstrates some Og features. The example
6
11
  automatically creates a 'test' database.
7
12
 
13
+
8
14
  == mock_example.rb
9
15
 
10
16
  Demonstrates how easily the Og infrastructure can be mocked,
11
17
  for easy test unit writing.
12
18
 
19
+
13
20
  == mysql_to_psql.rb
14
21
 
15
22
  Demonstrates how easy it is to migrate a mysql database
@@ -0,0 +1,152 @@
1
+ require 'facet/classinherit'
2
+
3
+ module Glue
4
+
5
+ # Include this module in your Og managed classes to make
6
+ # them cacheable. Only queries by id are cached.
7
+ #
8
+ # If you use a distributed cache (drb, memcache, etc) , you may
9
+ # have to start a separate server.
10
+ #
11
+ #--
12
+ # gmosx, WARNING: If the file lib/og/entity.rb is changed
13
+ # this file should be updated to reflect the changes!
14
+ #++
15
+
16
+ module Cacheable
17
+
18
+ ClassInherit do
19
+
20
+ def after_enchant(base)
21
+ base.module_eval do
22
+
23
+ alias_method :save_without_cache, :save
24
+ def save(options = nil)
25
+ Cacheable.cache_delete(self.class, pk)
26
+ val = save_without_cache(options)
27
+ Cacheable.cache_set(self)
28
+ return val
29
+ end
30
+ alias_method :save!, :save
31
+ alias_method :validate_and_save, :save
32
+
33
+ alias_method :force_save_without_cache!, :force_save!
34
+ def force_save!(options = nil)
35
+ Cacheable.cache_delete(self.class, pk)
36
+ val = force_save_without_cache!(options)
37
+ Cacheable.cache_set(self)
38
+ return val
39
+ end
40
+
41
+ alias_method :insert_without_cache, :insert
42
+ def insert
43
+ insert_without_cache()
44
+ Cacheable.cache_set(self)
45
+ return self
46
+ end
47
+
48
+ alias_method :update_without_cache, :update
49
+ def update(options = nil)
50
+ Cacheable.cache_delete(self.class, pk)
51
+ val = update_without_cache(options)
52
+ Cacheable.cache_set(self)
53
+ return val
54
+ end
55
+
56
+ alias_method :update_properties_without_cache, :update_properties
57
+ def update_properties(*properties)
58
+ Cacheable.cache_delete(self.class, pk)
59
+ val = update_properties_without_cache(*properties)
60
+ Cacheable.cache_set(self)
61
+ return val
62
+ end
63
+ alias_method :update_property, :update_properties
64
+ alias_method :pupdate, :update_properties
65
+
66
+ alias_method :update_by_sql_without_cache, :update_by_sql
67
+ def update_by_sql(set)
68
+ Cacheable.cache_delete(self.class, pk)
69
+ val = update_by_sql_without_cache(sql)
70
+ Cacheable.cache_set(self)
71
+ return val
72
+ end
73
+ alias_method :update_sql, :update_by_sql
74
+ alias_method :supdate, :update_by_sql
75
+
76
+ alias_method :reload_without_cache, :reload
77
+ def reload
78
+ Cacheable.cache_delete(self.class, pk)
79
+ reload_without_cache()
80
+ Cacheable.cache_set(self)
81
+ end
82
+ alias_method :reload!, :reload
83
+
84
+ alias_method :delete_without_cache, :delete
85
+ def delete(cascade = true)
86
+ delete_without_cache(cascade)
87
+ Cacheable.cache_delete(self.class, pk)
88
+ end
89
+
90
+ def og_cache_key
91
+ "#{self.class}:#{pk}"
92
+ end
93
+
94
+ class << self
95
+ alias_method :load_without_cache, :load
96
+ def load(pk)
97
+ key = og_cache_key(pk)
98
+ unless obj = ogmanager.cache.get(key)
99
+ obj = load_without_cache(pk)
100
+ ogmanager.cache.set(key, obj)
101
+ end
102
+
103
+ return obj
104
+ end
105
+ alias_method :[], :load
106
+ alias_method :exist?, :load
107
+
108
+ alias_method :delete_without_cache, :delete
109
+ def delete(obj_or_pk, cascade = true)
110
+ delete_without_cache(obj_or_pk, cascade)
111
+ Cacheable.cache_delete(self, obj_or_pk)
112
+ end
113
+
114
+ def og_cache_key(pk)
115
+ "#{self}:#{pk}"
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+ end
122
+
123
+ end
124
+
125
+ # ...
126
+
127
+ def self.cache_get(klass, pk)
128
+ end
129
+
130
+ # ...
131
+
132
+ def self.cache_set(obj)
133
+ obj.class.ogmanager.cache.set(obj.og_cache_key, obj)
134
+ end
135
+
136
+ # Invalidate the cache entry for an object. Og high level
137
+ # methods (for example the entity methods) automatically
138
+ # call this method where needed. However if you manually alter
139
+ # the store using Og low level methods (for example a native
140
+ # SQL query) you should call this method explicitly.
141
+
142
+ def self.cache_delete(klass, pk)
143
+ key = "og#{klass}:#{pk}"
144
+ # self.og_local_cache.delete(key)
145
+ klass.ogmanager.cache.delete(key)
146
+ end
147
+
148
+ end
149
+
150
+ end
151
+
152
+ # * George Moschovitis <gm@navel.gr>
@@ -1,5 +1,6 @@
1
- require 'mega/dynamod'
2
- require 'mega/orm_support'
1
+ require 'facet/ormsupport'
2
+
3
+ require 'glue/paramix'
3
4
 
4
5
  module Glue
5
6
 
@@ -11,7 +12,7 @@ module Glue
11
12
 
12
13
  module NestedSets
13
14
 
14
- def self.append_dynamic_features(base, options)
15
+ def self.included_with_params(base, options)
15
16
  c = {
16
17
  :left => 'lft',
17
18
  :right => 'rgt',
@@ -128,7 +129,7 @@ end
128
129
 
129
130
  module Hierarchical
130
131
 
131
- def self.append_dynamic_features(base, options)
132
+ def self.included_with_params(base, options)
132
133
  o = {
133
134
  :method => :nested_sets,
134
135
  }
@@ -1,4 +1,3 @@
1
- require 'mega/dynamod'
2
1
  require 'glue/on_included'
3
2
 
4
3
  module Glue
@@ -1,4 +1,4 @@
1
- require 'mega/dynamod'
1
+ require 'glue/paramix'
2
2
  require 'glue/aspects'
3
3
 
4
4
  module Glue
@@ -8,63 +8,65 @@ module Glue
8
8
  module Orderable
9
9
  include Glue::Aspects
10
10
 
11
- dynamic_feature do |opt|
11
+ def self.included_with_parameters(base, opt)
12
+ base.module_eval do
12
13
 
13
- opt_position = opt[:position] || 'position'
14
+ opt_position = opt[:position] || 'position'
14
15
 
15
- opt_type = opt[:type] || Fixnum
16
+ opt_type = opt[:type] || Fixnum
16
17
 
17
- # provide a user defined condition.
18
-
19
- opt_condition = opt[:condition]
18
+ # provide a user defined condition.
19
+
20
+ opt_condition = opt[:condition]
20
21
 
21
- # provide a condition based on a key field (?)
22
-
23
- opt_scope = opt[:scope]
22
+ # provide a condition based on a key field (?)
23
+
24
+ opt_scope = opt[:scope]
24
25
 
25
- # clean scope field.
26
-
27
- if opt_scope
28
- if opt_scope.to_s !~ /_oid$/
29
- opt_scope = "#{opt_scope}_oid".to_sym
30
- else
31
- opt_scope = opt_scope.to_sym
26
+ # clean scope field.
27
+
28
+ if opt_scope
29
+ if opt_scope.to_s !~ /_oid$/
30
+ opt_scope = "#{opt_scope}_oid".to_sym
31
+ else
32
+ opt_scope = opt_scope.to_sym
33
+ end
32
34
  end
33
- end
34
35
 
35
- define_method :orderable_position do
36
- opt_position
37
- end
36
+ define_method :orderable_position do
37
+ opt_position
38
+ end
38
39
 
39
- define_method :orderable_type do
40
- opt_type
41
- end
40
+ define_method :orderable_type do
41
+ opt_type
42
+ end
42
43
 
43
- define_method :orderable_scope do
44
- opt_scope
45
- end
44
+ define_method :orderable_scope do
45
+ opt_scope
46
+ end
46
47
 
47
- define_method :orderable_condition do
48
- scope = orderable_scope
49
- if scope
50
- scope_value = send(scope)
51
- scope = scope_value ? "#{scope} = #{scope_value}" : "#{scope} IS NULL"
48
+ define_method :orderable_condition do
49
+ scope = orderable_scope
50
+ if scope
51
+ scope_value = send(scope)
52
+ scope = scope_value ? "#{scope} = #{scope_value}" : "#{scope} IS NULL"
53
+ end
54
+ return [ opt_condition, scope ].compact
52
55
  end
53
- return [ opt_condition, scope ].compact
54
- end
55
56
 
56
- # How to check if property is already defined?
57
-
58
- unless method_defined?( opt_position )
59
- define_method( opt_position ) do @position ; end
60
- define_method( "#{opt_position}=" ) do |x| @position = x ; end
61
- property opt_position, opt_type
62
- end
57
+ # How to check if property is already defined?
58
+
59
+ unless method_defined?( opt_position )
60
+ define_method( opt_position ) do @position ; end
61
+ define_method( "#{opt_position}=" ) do |x| @position = x ; end
62
+ property opt_position, opt_type
63
+ end
63
64
 
64
- # Use position for general reference.
65
-
66
- attr_accessor :position
65
+ # Use position for general reference.
66
+
67
+ attr_accessor :position
67
68
 
69
+ end
68
70
  end #dynamic_feature
69
71
 
70
72
  before "add_to_bottom", :on => :og_insert