og 0.27.0 → 0.28.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|