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.
- data/ProjectInfo +2 -2
- data/README +8 -4
- data/Rakefile +1 -1
- data/doc/AUTHORS +1 -1
- data/doc/RELEASES +81 -0
- data/examples/README +7 -0
- data/lib/glue/cacheable.rb +152 -0
- data/lib/glue/hierarchical.rb +5 -4
- data/lib/glue/optimistic_locking.rb +0 -1
- data/lib/glue/orderable.rb +46 -44
- data/lib/glue/taggable.rb +7 -4
- data/lib/glue/timestamped.rb +1 -1
- data/lib/og.rb +13 -6
- data/lib/og/entity.rb +226 -9
- data/lib/og/evolution.rb +2 -2
- data/lib/og/ez/clause.rb +147 -0
- data/lib/og/ez/condition.rb +181 -0
- data/lib/og/manager.rb +31 -30
- data/lib/og/relation.rb +5 -5
- data/lib/og/relation/has_many.rb +3 -1
- data/lib/og/relation/joins_many.rb +1 -1
- data/lib/og/store.rb +6 -3
- data/lib/og/store/kirby.rb +3 -5
- data/lib/og/store/mysql.rb +0 -1
- data/lib/og/store/sql.rb +43 -7
- data/lib/og/store/sqlite.rb +97 -11
- data/lib/og/store/sqlite2.rb +231 -0
- data/lib/og/test/testcase.rb +1 -1
- data/lib/og/vendor/mysql.rb +103 -25
- data/test/glue/tc_revisable.rb +11 -11
- data/test/og/CONFIG.rb +20 -8
- data/test/og/mixin/tc_hierarchical.rb +5 -3
- data/test/og/mixin/tc_optimistic_locking.rb +6 -4
- data/test/og/mixin/tc_orderable.rb +22 -22
- data/test/og/mixin/tc_taggable.rb +15 -11
- data/test/og/mixin/tc_timestamped.rb +4 -2
- data/test/og/multi_validations_model.rb +8 -0
- data/test/og/store/tc_filesys.rb +15 -12
- data/test/og/store/tc_kirby.rb +14 -11
- data/test/og/tc_accumulator.rb +1 -3
- data/test/og/tc_cacheable.rb +58 -0
- data/test/og/tc_delete_all.rb +13 -16
- data/test/og/tc_ez.rb +33 -0
- data/test/og/tc_finder.rb +2 -4
- data/test/og/tc_inheritance.rb +3 -3
- data/test/og/tc_inheritance2.rb +2 -3
- data/test/og/tc_join.rb +3 -2
- data/test/og/tc_multi_validations.rb +3 -3
- data/test/og/tc_multiple.rb +3 -6
- data/test/og/tc_override.rb +19 -13
- data/test/og/tc_polymorphic.rb +1 -3
- data/test/og/tc_resolve.rb +32 -0
- data/test/og/tc_reverse.rb +27 -28
- data/test/og/tc_scoped.rb +2 -4
- data/test/og/tc_select.rb +1 -3
- data/test/og/tc_store.rb +3 -8
- data/test/og/tc_validation.rb +2 -2
- data/test/og/tc_validation2.rb +56 -58
- data/test/og/tc_validation_loop.rb +2 -5
- metadata +15 -7
- data/lib/og/vendor/mysql411.rb +0 -306
data/ProjectInfo
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
TITLE : &title Og
|
4
4
|
NAME : &pkg og
|
5
|
-
VERSION : '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.
|
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.
|
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,
|
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')
|
data/doc/AUTHORS
CHANGED
data/doc/RELEASES
CHANGED
@@ -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
|
data/examples/README
CHANGED
@@ -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>
|
data/lib/glue/hierarchical.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
require '
|
2
|
-
|
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.
|
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.
|
132
|
+
def self.included_with_params(base, options)
|
132
133
|
o = {
|
133
134
|
:method => :nested_sets,
|
134
135
|
}
|
data/lib/glue/orderable.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
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
|
-
|
11
|
+
def self.included_with_parameters(base, opt)
|
12
|
+
base.module_eval do
|
12
13
|
|
13
|
-
|
14
|
+
opt_position = opt[:position] || 'position'
|
14
15
|
|
15
|
-
|
16
|
+
opt_type = opt[:type] || Fixnum
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
# provide a user defined condition.
|
19
|
+
|
20
|
+
opt_condition = opt[:condition]
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
# provide a condition based on a key field (?)
|
23
|
+
|
24
|
+
opt_scope = opt[:scope]
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
36
|
+
define_method :orderable_position do
|
37
|
+
opt_position
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
define_method :orderable_type do
|
41
|
+
opt_type
|
42
|
+
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
44
|
+
define_method :orderable_scope do
|
45
|
+
opt_scope
|
46
|
+
end
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
65
|
-
|
66
|
-
|
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
|