og 0.22.0 → 0.23.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/INSTALL +2 -1
- data/README +2 -2
- data/Rakefile +1 -1
- data/{CHANGELOG → doc/CHANGELOG.1} +4 -0
- data/doc/RELEASES +53 -0
- data/examples/run.rb +1 -1
- data/lib/og.rb +11 -49
- data/lib/og/entity.rb +5 -0
- data/lib/og/errors.rb +2 -2
- data/lib/og/manager.rb +14 -8
- data/lib/og/mixin/hierarchical.rb +2 -5
- data/lib/og/mixin/optimistic_locking.rb +1 -1
- data/lib/og/mixin/orderable.rb +2 -2
- data/lib/og/mixin/revisable.rb +0 -0
- data/lib/og/mixin/taggable.rb +218 -0
- data/lib/og/relation.rb +39 -13
- data/lib/og/relation/has_many.rb +1 -3
- data/lib/og/relation/joins_many.rb +10 -4
- data/lib/og/relation/refers_to.rb +2 -2
- data/lib/og/store/mysql.rb +17 -0
- data/lib/og/store/psql.rb +2 -1
- data/lib/og/store/sql.rb +25 -4
- data/lib/og/store/sqlite.rb +1 -0
- data/lib/og/test/testcase.rb +1 -3
- data/lib/og/types.rb +3 -0
- data/test/og/mixin/tc_taggable.rb +69 -0
- data/test/og/tc_inheritance.rb +23 -4
- data/test/og/tc_override.rb +31 -0
- data/test/og/tc_store.rb +5 -5
- metadata +46 -42
data/INSTALL
CHANGED
data/README
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Og 0.
|
1
|
+
= Og 0.23.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
|
@@ -160,8 +160,8 @@ http://rubyforge.org/mailman/listinfo/nitro-general
|
|
160
160
|
|
161
161
|
== Licence
|
162
162
|
|
163
|
-
Copyright (c) 2004-2005, George 'tml' Moschovitis.
|
164
163
|
Copyright (c) 2004-2005, Navel Ltd (http://www.navel.gr)
|
164
|
+
Copyright (c) 2004-2005, George 'gmosx' Moschovitis (http://www.gmosx.com).
|
165
165
|
|
166
166
|
Og (http://www.nitrohq.com) is copyrighted free
|
167
167
|
software created and maintained by George Moschovitis (mailto:gm@navel.gr)
|
data/Rakefile
CHANGED
@@ -66,7 +66,7 @@ spec = Gem::Specification.new do |s|
|
|
66
66
|
|
67
67
|
s.files = FileList[
|
68
68
|
'[A-Z]*', 'install.rb', '{bin,benchmark,examples,doc,lib,test,vendor}/**/*'
|
69
|
-
].exclude(
|
69
|
+
].exclude("_darcs").exclude("_darcs/**/*").exclude('**/*.log').to_a
|
70
70
|
|
71
71
|
s.require_path = 'lib'
|
72
72
|
s.autorequire = 'og'
|
data/doc/RELEASES
CHANGED
@@ -1,3 +1,56 @@
|
|
1
|
+
== Version 0.23.0
|
2
|
+
|
3
|
+
The summer vacations are over and there is a brand new Nitro
|
4
|
+
release. There is a preview of the new Scaffolder (also handles
|
5
|
+
Og relations), lots of small features and improvements and many bug
|
6
|
+
fixes. Moreover the code has been restructured to utilize the
|
7
|
+
excellent Nano/Mega project as the support library.
|
8
|
+
|
9
|
+
Most notable additions:
|
10
|
+
|
11
|
+
* Scaffolding reloaded. The scaffolding infrastrucure is
|
12
|
+
reimplemented to generate more flexible code. The automatically
|
13
|
+
generated forms allow for visualisation and editing of
|
14
|
+
Og relations suchs as HasMany and BelongsTo.
|
15
|
+
|
16
|
+
Morover, an experimental admin component is provided. Just add the
|
17
|
+
line
|
18
|
+
|
19
|
+
require 'part/admin'
|
20
|
+
|
21
|
+
and surf
|
22
|
+
|
23
|
+
http://www.mysite.com/admin
|
24
|
+
|
25
|
+
To enter a simple administration screen. This feature is
|
26
|
+
considered a preview and will be improved in a future version.
|
27
|
+
|
28
|
+
* Introduced Og Taggable mixin. It was never easier to add
|
29
|
+
tagging to your appplication.
|
30
|
+
|
31
|
+
class Article
|
32
|
+
include Og::Taggable
|
33
|
+
..
|
34
|
+
end
|
35
|
+
|
36
|
+
article.tag('navel', 'gmosx', 'nitro')
|
37
|
+
article.tags
|
38
|
+
article.tag_names
|
39
|
+
Article.find_with_tags('navel', 'gmosx')
|
40
|
+
Article.find_with_any_tag('name', 'gmosx')
|
41
|
+
|
42
|
+
t = Article::Tag.find_by_name('ruby')
|
43
|
+
t.articles
|
44
|
+
t.articles.count
|
45
|
+
|
46
|
+
For an example usage of this Mixin, consult the Spark sources.
|
47
|
+
|
48
|
+
* Added support for 'evolving' a single Og managed class. Useful
|
49
|
+
when you are in development mode and change your schema.
|
50
|
+
|
51
|
+
* Many many small bug fixes.
|
52
|
+
|
53
|
+
|
1
54
|
== Version 0.22.0
|
2
55
|
|
3
56
|
A snapshot of the latest developments. Many requested features
|
data/examples/run.rb
CHANGED
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
3
|
# Copyright (c) 2004-2005, Navel Ltd (http://www.navel.gr)
|
4
|
+
# Copyright (c) 2004-2005, George Moschovitis (http://www.gmosx.com)
|
5
5
|
#
|
6
|
-
# Og is copyrighted free software
|
7
|
-
# George Moschovitis (mailto:gm@navel.gr)
|
8
|
-
# standard BSD Licence. For details
|
6
|
+
# Og (http://www.nitrohq.com) is copyrighted free software
|
7
|
+
# created and maintained by George Moschovitis (mailto:gm@navel.gr)
|
8
|
+
# and released under the standard BSD Licence. For details
|
9
|
+
# consult the file doc/LICENCE.
|
10
|
+
|
11
|
+
require 'mega/synchash'
|
12
|
+
require 'mega/syncarray'
|
9
13
|
|
10
14
|
require 'glue'
|
11
15
|
require 'glue/logger'
|
12
16
|
require 'glue/attribute'
|
13
17
|
require 'glue/property'
|
14
|
-
require 'glue/array'
|
15
|
-
require 'glue/hash'
|
16
|
-
require 'glue/time'
|
17
|
-
require 'glue/pool'
|
18
18
|
require 'glue/validation'
|
19
19
|
require 'glue/aspects'
|
20
20
|
require 'glue/configuration'
|
@@ -23,37 +23,6 @@ require 'glue/configuration'
|
|
23
23
|
# provides transparent and efficient object-relational mapping
|
24
24
|
# and querying mechanisms.
|
25
25
|
#
|
26
|
-
# === Features
|
27
|
-
#
|
28
|
-
# The library provides the following features:
|
29
|
-
#
|
30
|
-
# * Object-Relational mapping, automatically maps standard
|
31
|
-
# Ruby objects to sql schemas
|
32
|
-
# * Absolutely no configuration files.
|
33
|
-
# * Multiple stores (PostgreSQL, MySQL, SQLite, Oraclei, SqlServer, ..).
|
34
|
-
# * Supports non SQL stores (in-memory, filesystem, ..).
|
35
|
-
# * Can 'reverse engineer' legacy database schemase.
|
36
|
-
# * Fine-grained or High-level customization of the generated
|
37
|
-
# schema.
|
38
|
-
# * ActiveRecord-style domain specific language and db synchronized
|
39
|
-
# collections.
|
40
|
-
# * Transforms resultsets from arbitrary sql queries to Ruby objects.
|
41
|
-
# * Independent store for each object class, can support multiple
|
42
|
-
# stores in the same application.
|
43
|
-
# * Deserialize to Ruby Objects.
|
44
|
-
# * Deserialize sql join queries to Ruby Objects.
|
45
|
-
# * Eager associations.
|
46
|
-
# * Serialize arbitrary ruby object graphs through YAML.
|
47
|
-
# * Connection pooling.
|
48
|
-
# * Thread safety.
|
49
|
-
# * SQL transactions.
|
50
|
-
# * Aspect oriented constructs allow interception of lifecycle callbacks.
|
51
|
-
# * Transparent support for cascading deletes for all backends.
|
52
|
-
# * Hierarchical structures (nested sets)
|
53
|
-
# * Works safely as part of distributed application.
|
54
|
-
# * Optimistic locking.
|
55
|
-
# * Simple implementation.
|
56
|
-
#
|
57
26
|
# === Property Metadata
|
58
27
|
#
|
59
28
|
# Og defines, reserves and uses the following property
|
@@ -71,19 +40,12 @@ require 'glue/configuration'
|
|
71
40
|
# mark them as Object (or Array or Hash) in the prop_accessor
|
72
41
|
# and the engine will serialize a YAML dump of the object.
|
73
42
|
# Arbitrary object graphs are supported too.
|
74
|
-
#
|
75
|
-
# === Lifecycle Callbacks
|
76
|
-
#
|
77
|
-
# * og_read
|
78
|
-
# * og_insert
|
79
|
-
# * og_update
|
80
|
-
# * og_delete
|
81
43
|
|
82
44
|
module Og
|
83
45
|
|
84
46
|
# The version.
|
85
47
|
|
86
|
-
Version = '0.
|
48
|
+
Version = '0.23.0'
|
87
49
|
|
88
50
|
# Library path.
|
89
51
|
|
@@ -170,11 +132,11 @@ module Og
|
|
170
132
|
|
171
133
|
end
|
172
134
|
|
135
|
+
#--
|
173
136
|
# gmosx: leave this here.
|
137
|
+
#++
|
174
138
|
|
175
139
|
require 'og/manager'
|
176
140
|
require 'og/errors'
|
177
141
|
require 'og/types'
|
178
142
|
require 'og/validation'
|
179
|
-
|
180
|
-
# * George Moschovitis <gm@navel.gr>
|
data/lib/og/entity.rb
CHANGED
data/lib/og/errors.rb
CHANGED
data/lib/og/manager.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mega/pool'
|
2
|
+
|
1
3
|
require 'og/entity'
|
2
4
|
require 'og/store'
|
3
5
|
|
@@ -38,7 +40,7 @@ class Manager
|
|
38
40
|
def initialize(options)
|
39
41
|
@options = options
|
40
42
|
@entities = {}
|
41
|
-
@pool =
|
43
|
+
@pool = Pool.new
|
42
44
|
|
43
45
|
@store_class = Store.for_name(options[:store])
|
44
46
|
@store_class.destroy(options) if options[:destroy]
|
@@ -108,11 +110,6 @@ class Manager
|
|
108
110
|
|
109
111
|
info = EntityInfo.new(klass)
|
110
112
|
|
111
|
-
# ensure that the superclass is managed before the
|
112
|
-
# subclass.
|
113
|
-
|
114
|
-
manage(klass.superclass) if has_super?(klass)
|
115
|
-
|
116
113
|
klass.module_eval %{
|
117
114
|
def ==(other)
|
118
115
|
other ? @#{klass.primary_key.first} == other.#{klass.primary_key.first} : false
|
@@ -123,6 +120,11 @@ class Manager
|
|
123
120
|
klass.class.send(:attr_accessor, :ogmanager)
|
124
121
|
|
125
122
|
Relation.enchant(klass)
|
123
|
+
|
124
|
+
# ensure that the superclass is managed before the
|
125
|
+
# subclass.
|
126
|
+
|
127
|
+
manage(klass.superclass) if has_super?(klass)
|
126
128
|
|
127
129
|
# FIXME: uggly!
|
128
130
|
store.enchant(klass, self); put_store
|
@@ -167,8 +169,6 @@ class Manager
|
|
167
169
|
end
|
168
170
|
end
|
169
171
|
|
170
|
-
Logger.debug "Og manageable classes: #{classes.inspect}" if $DBG
|
171
|
-
|
172
172
|
return classes
|
173
173
|
end
|
174
174
|
|
@@ -176,6 +176,9 @@ class Manager
|
|
176
176
|
|
177
177
|
def manage_classes(*classes)
|
178
178
|
classes = manageable_classes.flatten if classes.empty?
|
179
|
+
|
180
|
+
Logger.debug "Og manageable classes: #{classes.inspect}" if $DBG
|
181
|
+
|
179
182
|
classes.each { |c| resolve_inheritance(c) }
|
180
183
|
classes.each { |c| Relation.resolve(c, :resolve_target) }
|
181
184
|
classes.each { |c| Relation.resolve(c, :resolve_polymorphic) }
|
@@ -187,3 +190,6 @@ class Manager
|
|
187
190
|
end
|
188
191
|
|
189
192
|
end
|
193
|
+
|
194
|
+
# * George Moschovitis <gm@navel.gr>
|
195
|
+
# * Guillaume Pierronnet <guillaume.pierronnet@laposte.net>
|
data/lib/og/mixin/orderable.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'mega/macro'
|
2
2
|
|
3
3
|
module Og
|
4
4
|
|
@@ -25,7 +25,7 @@ module Orderable
|
|
25
25
|
scope = %{(#{scope} ? "#{scope} = \#{@#{scope}}" : "#{scope} IS NULL")}
|
26
26
|
end
|
27
27
|
|
28
|
-
cond = 'condition => ' + scope
|
28
|
+
cond = ':condition => ' + scope
|
29
29
|
cond_and = ':condition => ' + scope + ' + " AND " +'
|
30
30
|
else
|
31
31
|
cond = ':condition => nil'
|
File without changes
|
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'mega/macro'
|
2
|
+
require 'nano/object/assign_with'
|
3
|
+
|
4
|
+
#--
|
5
|
+
# gmosx: make polymorphic work with many_to_many.
|
6
|
+
#++
|
7
|
+
|
8
|
+
module Og
|
9
|
+
|
10
|
+
# The default Tag implementation. A tag attaches semantics to
|
11
|
+
# a given object.
|
12
|
+
#--
|
13
|
+
# FIXME: use index and char() instead of String.
|
14
|
+
#++
|
15
|
+
|
16
|
+
class Tag
|
17
|
+
property :name, String, :uniq => true
|
18
|
+
|
19
|
+
def initialize(name = nil)
|
20
|
+
@name = name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Add tagging methods to the target class.
|
25
|
+
# For more information on the algorithms used surf:
|
26
|
+
# http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html
|
27
|
+
#
|
28
|
+
# === Example
|
29
|
+
#
|
30
|
+
# class Article
|
31
|
+
# include Taggable
|
32
|
+
# ..
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# article.tag('navel', 'gmosx', 'nitro')
|
36
|
+
# article.tags
|
37
|
+
# article.tag_names
|
38
|
+
# Article.find_with_tags('navel', 'gmosx')
|
39
|
+
# Article.find_with_any_tag('name', 'gmosx')
|
40
|
+
#
|
41
|
+
# Article::Tag.find_by_name('ruby').articles
|
42
|
+
|
43
|
+
module Taggable
|
44
|
+
|
45
|
+
# Helper.
|
46
|
+
|
47
|
+
def self.tags_to_names(the_tags, separator = ' ')
|
48
|
+
if the_tags.is_a? Array
|
49
|
+
names = the_tags
|
50
|
+
elsif the_tags.is_a? String
|
51
|
+
names = the_tags.split(separator)
|
52
|
+
end
|
53
|
+
|
54
|
+
names = names.flatten.uniq.compact
|
55
|
+
|
56
|
+
return names
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.append_dynamic_features(base, options = nil)
|
60
|
+
o = {
|
61
|
+
:base_tag_class => Og::Tag,
|
62
|
+
:separator => ' '
|
63
|
+
}
|
64
|
+
o.update(options) if options
|
65
|
+
|
66
|
+
code = ''
|
67
|
+
|
68
|
+
unless o[:tag_class]
|
69
|
+
o[:tag_class] = 'Tag'
|
70
|
+
code << %{
|
71
|
+
class #{o[:tag_class]} < #{o[:base_tag_class]}
|
72
|
+
many_to_many #{base}, :foreign_name => :tags
|
73
|
+
end
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
tag_class = o[:tag_class]
|
78
|
+
separator = o[:separator].inspect
|
79
|
+
|
80
|
+
code << %{
|
81
|
+
many_to_many :tags, #{o[:tag_class]}
|
82
|
+
}
|
83
|
+
|
84
|
+
# Instance Methods:
|
85
|
+
|
86
|
+
# Apply a collection of tags to the object.
|
87
|
+
# +tags+ can be either an array or a String.
|
88
|
+
#
|
89
|
+
# === Options
|
90
|
+
#
|
91
|
+
# +clear+: clear the tags collection before adding the
|
92
|
+
# new tags.
|
93
|
+
|
94
|
+
code << %{
|
95
|
+
def tag(the_tags, options = {})
|
96
|
+
options = {
|
97
|
+
:clear => true
|
98
|
+
}.merge(options)
|
99
|
+
|
100
|
+
names = Taggable.tags_to_names(the_tags, #{separator})
|
101
|
+
|
102
|
+
tags.load_members
|
103
|
+
|
104
|
+
# clear the collection if needed.
|
105
|
+
|
106
|
+
self.tags.clear if options[:clear]
|
107
|
+
|
108
|
+
# append the tag names to the collection
|
109
|
+
|
110
|
+
names.each do |name|
|
111
|
+
name = name.strip
|
112
|
+
unless tagged_with?(name)
|
113
|
+
unless tag_obj = #{tag_class}.find_by_name(name)
|
114
|
+
tag_obj = #{tag_class}.create(name)
|
115
|
+
end
|
116
|
+
tags << tag_obj
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
self.save
|
121
|
+
end
|
122
|
+
}
|
123
|
+
|
124
|
+
# Clears all tags.
|
125
|
+
|
126
|
+
def delete_tags
|
127
|
+
end
|
128
|
+
alias_method :clear_tags, :delete_tags
|
129
|
+
|
130
|
+
# Returns an array of strings containing the tags applied to
|
131
|
+
# this object.
|
132
|
+
|
133
|
+
code << %{
|
134
|
+
def tag_names
|
135
|
+
tags.map { |t| t.name }
|
136
|
+
end
|
137
|
+
}
|
138
|
+
|
139
|
+
# Checks to see if this object has been tagged
|
140
|
+
# with +tag_name+.
|
141
|
+
|
142
|
+
code << %{
|
143
|
+
def tagged_with?(tag_name)
|
144
|
+
tag_names.include?(tag_name)
|
145
|
+
end
|
146
|
+
alias_method :tagged_by?, :tagged_with?
|
147
|
+
}
|
148
|
+
|
149
|
+
# Class Methods:
|
150
|
+
|
151
|
+
code << %{
|
152
|
+
class << self
|
153
|
+
}
|
154
|
+
|
155
|
+
# Find objects with all of the provided tags.
|
156
|
+
# INTERSECTION (AND)
|
157
|
+
#--
|
158
|
+
# TODO: move info out of compiled code.
|
159
|
+
#++
|
160
|
+
|
161
|
+
code << %{
|
162
|
+
def find_with_tags(*names)
|
163
|
+
info = ogmanager.store.join_table_info(#{base}, #{tag_class})
|
164
|
+
count = names.size
|
165
|
+
names = names.map { |n| "'\#{n}'" }.join(',')
|
166
|
+
sql = %{
|
167
|
+
SELECT o.*
|
168
|
+
FROM
|
169
|
+
\#{info[:first_table]} AS o,
|
170
|
+
\#{info[:second_table]} as t,
|
171
|
+
\#{info[:table]} as j
|
172
|
+
WHERE o.oid = j.\#{info[:first_key]}
|
173
|
+
AND t.oid = j.\#{info[:second_key]}
|
174
|
+
AND (t.name in (\#{names}))
|
175
|
+
GROUP BY o.oid
|
176
|
+
HAVING COUNT(o.oid) = \#{count};
|
177
|
+
}
|
178
|
+
return self.select(sql)
|
179
|
+
end
|
180
|
+
alias_method :find_with_tag, :find_with_tags
|
181
|
+
}
|
182
|
+
|
183
|
+
# Find objects with any of the provided tags.
|
184
|
+
# UNION (OR)
|
185
|
+
|
186
|
+
code << %{
|
187
|
+
def find_with_any_tag(*names)
|
188
|
+
info = ogmanager.store.join_table_info(#{base}, #{tag_class})
|
189
|
+
count = names.size
|
190
|
+
names = names.map { |n| "'\#{n}'" }.join(',')
|
191
|
+
sql = %{
|
192
|
+
SELECT o.*
|
193
|
+
FROM
|
194
|
+
\#{info[:first_table]} AS o,
|
195
|
+
\#{info[:second_table]} as t,
|
196
|
+
\#{info[:table]} as j
|
197
|
+
WHERE
|
198
|
+
o.oid = j.\#{info[:first_key]}
|
199
|
+
AND t.oid = j.\#{info[:second_key]}
|
200
|
+
AND (t.name in (\#{names}))
|
201
|
+
GROUP BY o.oid
|
202
|
+
}
|
203
|
+
return self.select(sql)
|
204
|
+
end
|
205
|
+
}
|
206
|
+
|
207
|
+
code << %{
|
208
|
+
end
|
209
|
+
}
|
210
|
+
|
211
|
+
base.module_eval(code)
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/og/relation.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
|
4
|
-
require '
|
1
|
+
require 'nano/object/constant'
|
2
|
+
require 'nano/string/capitalized%3F'
|
3
|
+
|
4
|
+
require 'mega/orm_support'
|
5
5
|
|
6
6
|
module Og
|
7
7
|
|
8
|
-
# A relation between Entities.
|
8
|
+
# A relation between Entities.
|
9
9
|
|
10
10
|
class Relation
|
11
11
|
|
12
|
+
# The parameters of this relation.
|
13
|
+
|
12
14
|
attr_accessor :options
|
13
15
|
|
16
|
+
# Is this a polymorphic relation?
|
17
|
+
|
14
18
|
attr_accessor :is_polymorphic
|
15
19
|
|
16
20
|
# A generalized initialize method for all relations.
|
@@ -20,18 +24,34 @@ class Relation
|
|
20
24
|
@options = options
|
21
25
|
@options.update(args.pop) if args.last.is_a?(Hash)
|
22
26
|
|
23
|
-
if args.empty? or (not (args.last.is_a?(Class) or args.last.is_a?(Symbol)))
|
24
|
-
raise 'Class of target not defined'
|
25
|
-
end
|
26
|
-
|
27
27
|
target_name = if collection
|
28
28
|
:target_plural_name
|
29
29
|
else
|
30
30
|
:target_singular_name
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
# Check that all needed options are provided.
|
34
|
+
|
35
|
+
if args.empty? or (not (args.last.is_a?(Class) or args.last.is_a?(Symbol)))
|
36
|
+
raise 'Class of target not defined'
|
37
|
+
end
|
38
|
+
|
39
|
+
# Try to set the target class. Checks for class and
|
40
|
+
# class symbol.
|
41
|
+
|
42
|
+
if args.last.to_s.capitalized?
|
43
|
+
@options[:target_class] = args.pop
|
44
|
+
end
|
45
|
+
|
46
|
+
# Try to set the target name.
|
47
|
+
|
48
|
+
if args.last.is_a? Symbol
|
49
|
+
@options[target_name] = args.pop
|
50
|
+
end
|
51
|
+
|
52
|
+
# Inflect target_class if not provided.
|
53
|
+
|
54
|
+
@options[:target_class] ||= @options[target_name].to_s.singular.camelize.intern
|
35
55
|
|
36
56
|
setup()
|
37
57
|
end
|
@@ -193,7 +213,8 @@ module RelationMacros
|
|
193
213
|
|
194
214
|
# === Examples
|
195
215
|
#
|
196
|
-
# belongs_to Article
|
216
|
+
# belongs_to :article # inflects Article
|
217
|
+
# belongs_to Article # inflects :article
|
197
218
|
# belongs_to :article, Article
|
198
219
|
# belongs_to :article, Article, :view => 'lala'
|
199
220
|
|
@@ -204,7 +225,8 @@ module RelationMacros
|
|
204
225
|
|
205
226
|
# === Examples
|
206
227
|
#
|
207
|
-
#
|
228
|
+
# refers_to :topic # inflects Topic
|
229
|
+
# refers_to Topic # inflects :topic
|
208
230
|
|
209
231
|
def refers_to(*args)
|
210
232
|
require 'og/relation/refers_to'
|
@@ -230,11 +252,15 @@ module RelationMacros
|
|
230
252
|
meta :relations, Og::HasMany.new(args, :owner_class => self, :collection => true)
|
231
253
|
end
|
232
254
|
|
255
|
+
# ..
|
256
|
+
|
233
257
|
def joins_many(*args)
|
234
258
|
require 'og/relation/joins_many'
|
235
259
|
meta :relations, Og::JoinsMany.new(args, :owner_class => self, :collection => true)
|
236
260
|
end
|
237
261
|
|
262
|
+
# ..
|
263
|
+
|
238
264
|
def many_to_many(*args)
|
239
265
|
require 'og/relation/many_to_many'
|
240
266
|
meta :relations, Og::ManyToMany.new(args, :owner_class => self, :collection => true)
|
data/lib/og/relation/has_many.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require 'facet/string/demodulize'
|
3
|
-
require 'facet/string/underscore'
|
1
|
+
require 'mega/orm_support'
|
4
2
|
|
5
3
|
require 'og/relation'
|
6
4
|
require 'og/collection'
|
@@ -26,8 +24,15 @@ class JoinsMany < Relation
|
|
26
24
|
self[:target_singular_name] = target_plural_name.to_s.singular
|
27
25
|
|
28
26
|
store = owner_class.ogmanager.store
|
29
|
-
|
27
|
+
|
28
|
+
# handle schema_inheritance
|
30
29
|
|
30
|
+
join_class = owner_class
|
31
|
+
if sclass = owner_class.metadata.superclass
|
32
|
+
join_class = sclass.first
|
33
|
+
end
|
34
|
+
join_table_info = store.join_table_info(join_class, target_class)
|
35
|
+
|
31
36
|
if through = self[:through]
|
32
37
|
# A custom class is used for the join. Use the class
|
33
38
|
# table and don't create a new table.
|
@@ -118,3 +123,4 @@ end
|
|
118
123
|
|
119
124
|
# * George Moschovitis <gm@navel.gr>
|
120
125
|
# * Ysabel <deb@ysabel.org>
|
126
|
+
# * Guillaume Pierronnet <guillaume.pierronnet@laposte.net>
|
@@ -13,7 +13,7 @@ class RefersTo < Relation
|
|
13
13
|
|
14
14
|
owner_class.module_eval %{
|
15
15
|
attr_accessor :#{target_singular_name}
|
16
|
-
prop_accessor :#{foreign_key}, #{target_pkclass}#{field}
|
16
|
+
prop_accessor :#{foreign_key}, #{target_pkclass}#{field}, :relation => true
|
17
17
|
|
18
18
|
def #{target_singular_name}(reload = false)
|
19
19
|
return nil if @#{foreign_key}.nil?
|
@@ -28,7 +28,7 @@ class RefersTo < Relation
|
|
28
28
|
def #{target_singular_name}=(obj)
|
29
29
|
@#{foreign_key} = obj.#{target_pk} if obj
|
30
30
|
end
|
31
|
-
}
|
31
|
+
}
|
32
32
|
end
|
33
33
|
|
34
34
|
end
|
data/lib/og/store/mysql.rb
CHANGED
@@ -12,6 +12,20 @@ rescue Object => ex
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
# Helper for scripts.
|
16
|
+
#
|
17
|
+
# === Example
|
18
|
+
#
|
19
|
+
# mysql "-u root -p", <<-END
|
20
|
+
# drop database if exists weblog_development;
|
21
|
+
# create database weblog_development;
|
22
|
+
# grant all on weblog_development.* to #{`id -un`.strip}@localhost;
|
23
|
+
# END
|
24
|
+
|
25
|
+
def mysql(opts, stream)
|
26
|
+
IO.popen("mysql #{opts}", 'w') { |io| io.puts stream }
|
27
|
+
end
|
28
|
+
|
15
29
|
require 'og/store/sql'
|
16
30
|
|
17
31
|
# Customize the standard mysql resultset to make
|
@@ -232,6 +246,7 @@ private
|
|
232
246
|
create_join_table_sql(info).each do |sql|
|
233
247
|
@conn.query sql
|
234
248
|
end
|
249
|
+
Logger.debug "Created jointable '#{info[:table]}'."
|
235
250
|
rescue => ex
|
236
251
|
if ex.respond_to?(:errno) and ex.errno == 1050 # table already exists.
|
237
252
|
Logger.debug 'Join table already exists' if $DBG
|
@@ -320,3 +335,5 @@ private
|
|
320
335
|
end
|
321
336
|
|
322
337
|
end
|
338
|
+
|
339
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/og/store/psql.rb
CHANGED
@@ -203,7 +203,7 @@ private
|
|
203
203
|
rescue Object => ex
|
204
204
|
# gmosx: any idea how to better test this?
|
205
205
|
if ex.to_s =~ /relation .* already exists/i
|
206
|
-
Logger.debug 'Table already exists'
|
206
|
+
Logger.debug 'Table already exists'
|
207
207
|
return
|
208
208
|
else
|
209
209
|
raise
|
@@ -219,6 +219,7 @@ private
|
|
219
219
|
create_join_table_sql(info).each do |sql|
|
220
220
|
@conn.exec(sql).clear
|
221
221
|
end
|
222
|
+
Logger.debug "Created jointable '#{info[:table]}'."
|
222
223
|
rescue Object => ex
|
223
224
|
# gmosx: any idea how to better test this?
|
224
225
|
if ex.to_s =~ /relation .* already exists/i
|
data/lib/og/store/sql.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'nano/object/constant'
|
4
4
|
|
5
5
|
module Og
|
6
6
|
|
@@ -323,7 +323,7 @@ class SqlStore < Store
|
|
323
323
|
# selected properties. Pass the required properties as symbols
|
324
324
|
# or strings.
|
325
325
|
#--
|
326
|
-
# gmosx,
|
326
|
+
# gmosx, THINK: condition is not really useful here :(
|
327
327
|
#++
|
328
328
|
|
329
329
|
def update(obj, options = nil)
|
@@ -445,7 +445,7 @@ class SqlStore < Store
|
|
445
445
|
|
446
446
|
def unjoin(obj1, obj2, table)
|
447
447
|
first, second = join_object_ordering(obj1, obj2)
|
448
|
-
first_key, second_key = ordered_join_table_keys(obj1, obj2
|
448
|
+
first_key, second_key = ordered_join_table_keys(obj1.class, obj2.class)
|
449
449
|
exec "DELETE FROM #{table} WHERE #{first_key}=#{first.pk} AND #{second_key}=#{second.pk}"
|
450
450
|
end
|
451
451
|
|
@@ -483,6 +483,9 @@ class SqlStore < Store
|
|
483
483
|
|
484
484
|
private
|
485
485
|
|
486
|
+
# Create the sql table where objects of this class are
|
487
|
+
# persisted.
|
488
|
+
|
486
489
|
def create_table(klass)
|
487
490
|
raise 'Not implemented'
|
488
491
|
end
|
@@ -494,6 +497,15 @@ private
|
|
494
497
|
exec "DROP TABLE #{klass.table}"
|
495
498
|
end
|
496
499
|
|
500
|
+
# Evolve (recreate) the sql table where objects of this class
|
501
|
+
# are persisted.
|
502
|
+
|
503
|
+
def evolve_table(klass)
|
504
|
+
drop_table(klass)
|
505
|
+
create_table(klass)
|
506
|
+
end
|
507
|
+
alias_method :update_table, :evolve_table
|
508
|
+
|
497
509
|
# Return the field for the given property.
|
498
510
|
|
499
511
|
def field_for_property(property)
|
@@ -772,7 +784,15 @@ private
|
|
772
784
|
if rel = klass.relation(name)
|
773
785
|
target_table = rel[:target_class]::OGTABLE
|
774
786
|
tables << target_table
|
775
|
-
|
787
|
+
# join_conditions << "#{klass::OGTABLE}.#{rel[:foreign_key]}=#{target_table}.#{rel[:target_pk]}"
|
788
|
+
if rel.is_a?(JoinsMany)
|
789
|
+
tables << rel[:join_table]
|
790
|
+
owner_key, target_key = klass.ogmanager.store.join_table_keys(klass, rel[:target_class])
|
791
|
+
join_conditions << "#{rel[:join_table]}.#{owner_key}=#{klass::OGTABLE}.#{rel[:owner_pk]} AND \
|
792
|
+
#{rel[:join_table]}.#{target_key}=#{rel[:target_class]::OGTABLE}.#{rel[:target_pk]}"
|
793
|
+
else
|
794
|
+
join_conditions << "#{klass::OGTABLE}.#{rel[:foreign_key]}=#{target_table}.#{rel[:target_pk]}"
|
795
|
+
end
|
776
796
|
else
|
777
797
|
raise 'Unknown relation name'
|
778
798
|
end
|
@@ -940,3 +960,4 @@ end
|
|
940
960
|
# * Michael Neumann <mneumann@ntecs.de>
|
941
961
|
# * Ghislain Mary
|
942
962
|
# * Ysabel <deb@ysabel.org>
|
963
|
+
# * Guillaume Pierronnet <guillaume.pierronnet@laposte.net>
|
data/lib/og/store/sqlite.rb
CHANGED
@@ -159,6 +159,7 @@ private
|
|
159
159
|
create_join_table_sql(info).each do |sql|
|
160
160
|
@conn.query(sql).close
|
161
161
|
end
|
162
|
+
Logger.debug "Created jointable '#{info[:table]}'."
|
162
163
|
rescue Object => ex
|
163
164
|
# gmosx: any idea how to better test this?
|
164
165
|
if ex.to_s =~ /table .* already exists/i
|
data/lib/og/test/testcase.rb
CHANGED
data/lib/og/types.rb
CHANGED
@@ -0,0 +1,69 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
require 'og'
|
7
|
+
require 'og/mixin/taggable'
|
8
|
+
|
9
|
+
class Article
|
10
|
+
property :title, :body, String
|
11
|
+
include Og::Taggable
|
12
|
+
|
13
|
+
def initialize(title = nil)
|
14
|
+
@title = title
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
$og = Og.setup(
|
19
|
+
:store => 'mysql',
|
20
|
+
:name => 'test',
|
21
|
+
:user => 'root',
|
22
|
+
:password => 'navelrulez',
|
23
|
+
:destroy => true
|
24
|
+
)
|
25
|
+
|
26
|
+
class TestOgTaggable < Test::Unit::TestCase # :nodoc: all
|
27
|
+
|
28
|
+
def test_all
|
29
|
+
a1 = Article.create('Hello')
|
30
|
+
a1.tag('navel gmosx sexy')
|
31
|
+
a1.save
|
32
|
+
|
33
|
+
a2 = Article.create('Other')
|
34
|
+
a2.tag('gmosx', 'rain')
|
35
|
+
a2.save
|
36
|
+
|
37
|
+
a3 = Article.create('George')
|
38
|
+
a3.tag('phd', 'name')
|
39
|
+
a3.save
|
40
|
+
|
41
|
+
assert_equal 3, a1.tags.size
|
42
|
+
assert a1.tag_names.include?('navel')
|
43
|
+
|
44
|
+
assert a1.tagged_with?('navel')
|
45
|
+
|
46
|
+
assert_equal false, a1.tagged_with?('photo')
|
47
|
+
|
48
|
+
res = Article.find_with_tags('navel', 'gmosx')
|
49
|
+
assert_equal 1, res.size
|
50
|
+
assert_equal 'Hello', res[0].title
|
51
|
+
|
52
|
+
res = Article.find_with_tag('gmosx')
|
53
|
+
assert_equal 2, res.size
|
54
|
+
res = res.map { |o| o.title }
|
55
|
+
assert res.include?('Hello')
|
56
|
+
assert res.include?('Other')
|
57
|
+
|
58
|
+
res = Article.find_with_any_tag('navel', 'gmosx', 'phd')
|
59
|
+
assert_equal 3, res.size
|
60
|
+
|
61
|
+
=begin
|
62
|
+
TODO:
|
63
|
+
Article.fing_with_no_tag('gmosx')
|
64
|
+
Article.find_by_tags('+name +gmosx -sexy')
|
65
|
+
Article.find_by_tags(:with => '', :any => '', :no => '')
|
66
|
+
=end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/test/og/tc_inheritance.rb
CHANGED
@@ -34,6 +34,21 @@ class TC_OgInheritance < Test::Unit::TestCase # :nodoc: all
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
class Car
|
38
|
+
property :name
|
39
|
+
end
|
40
|
+
|
41
|
+
class User
|
42
|
+
property :login, String
|
43
|
+
many_to_many Car
|
44
|
+
schema_inheritance
|
45
|
+
end
|
46
|
+
|
47
|
+
class Admin < User
|
48
|
+
property :password, String
|
49
|
+
has_one Car
|
50
|
+
end
|
51
|
+
|
37
52
|
def test_all
|
38
53
|
=begin
|
39
54
|
@og = Og.setup(
|
@@ -48,7 +63,7 @@ class TC_OgInheritance < Test::Unit::TestCase # :nodoc: all
|
|
48
63
|
:name => 'test'
|
49
64
|
)
|
50
65
|
=end
|
51
|
-
|
66
|
+
=begin
|
52
67
|
@og = Og.setup(
|
53
68
|
:destroy => true,
|
54
69
|
:store => :psql,
|
@@ -56,8 +71,8 @@ class TC_OgInheritance < Test::Unit::TestCase # :nodoc: all
|
|
56
71
|
:user => 'postgres',
|
57
72
|
:password => 'navelrulez'
|
58
73
|
)
|
59
|
-
|
60
|
-
|
74
|
+
=end
|
75
|
+
#=begin
|
61
76
|
@og = Og.setup(
|
62
77
|
:destroy => true,
|
63
78
|
:store => :mysql,
|
@@ -65,7 +80,7 @@ class TC_OgInheritance < Test::Unit::TestCase # :nodoc: all
|
|
65
80
|
:user => 'root',
|
66
81
|
:password => 'navelrulez'
|
67
82
|
)
|
68
|
-
|
83
|
+
#=end
|
69
84
|
assert_equal [Document], Photo.metadata.superclass
|
70
85
|
assert_equal [Photo, Article], Document.metadata.subclasses
|
71
86
|
|
@@ -108,5 +123,9 @@ class TC_OgInheritance < Test::Unit::TestCase # :nodoc: all
|
|
108
123
|
|
109
124
|
articles = Article.all(:limit => 2)
|
110
125
|
assert_equal 2, articles.size
|
126
|
+
|
127
|
+
# Bug report.
|
128
|
+
Admin.create
|
129
|
+
Admin.create.cars.size
|
111
130
|
end
|
112
131
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
$DBG = true
|
2
|
+
|
3
|
+
require 'og'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class Book
|
7
|
+
property :title
|
8
|
+
belongs_to :owner, Person # this creates a problem?
|
9
|
+
end
|
10
|
+
|
11
|
+
class Person
|
12
|
+
property :name, Og::VarChar(128)
|
13
|
+
has_many :books, Book, :foreign_name => :owner
|
14
|
+
end
|
15
|
+
|
16
|
+
class TestOg < Test::Unit::TestCase
|
17
|
+
include Og
|
18
|
+
|
19
|
+
def test_basic
|
20
|
+
book = Book.create
|
21
|
+
person = Person.create
|
22
|
+
person.books << book
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup
|
26
|
+
Og.table_prefix = nil
|
27
|
+
og = Og.setup(:destroy => true, :store => :sqlite, :name => 'test')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# * Kristof Jozsa <dyn@ond.vein.hu>
|
data/test/og/tc_store.rb
CHANGED
@@ -31,7 +31,7 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
31
31
|
|
32
32
|
class Article
|
33
33
|
property :title, :body, String
|
34
|
-
has_many
|
34
|
+
has_many :comments
|
35
35
|
has_one :author, User
|
36
36
|
refers_to :owner, User
|
37
37
|
many_to_many Category
|
@@ -103,7 +103,7 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
103
103
|
conversions_test
|
104
104
|
end
|
105
105
|
=end
|
106
|
-
|
106
|
+
=begin
|
107
107
|
def test_mysql
|
108
108
|
@og = Og.setup(
|
109
109
|
:destroy => true,
|
@@ -116,8 +116,8 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
116
116
|
features_test
|
117
117
|
# conversions_test
|
118
118
|
end
|
119
|
-
|
120
|
-
|
119
|
+
=end
|
120
|
+
#=begin
|
121
121
|
def test_sqlite
|
122
122
|
@og = Og.setup(
|
123
123
|
:destroy => true,
|
@@ -127,7 +127,7 @@ class TCOgStore < Test::Unit::TestCase # :nodoc: all
|
|
127
127
|
features_test
|
128
128
|
conversions_test
|
129
129
|
end
|
130
|
-
|
130
|
+
#=end
|
131
131
|
=begin
|
132
132
|
def test_memory
|
133
133
|
@og = Og.setup(
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: og
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2005-08-
|
6
|
+
version: 0.23.0
|
7
|
+
date: 2005-08-31 00:00:00 +03:00
|
8
8
|
summary: Og (ObjectGraph)
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -29,82 +29,86 @@ cert_chain:
|
|
29
29
|
authors:
|
30
30
|
- George Moschovitis
|
31
31
|
files:
|
32
|
+
- Rakefile
|
32
33
|
- README
|
33
|
-
- CHANGELOG
|
34
34
|
- INSTALL
|
35
|
-
- Rakefile
|
36
35
|
- install.rb
|
37
|
-
- benchmark/bench.rb
|
38
|
-
- benchmark/sqlite-no-prepare.1.txt
|
39
|
-
- benchmark/sqlite-no-prepare.2.txt
|
40
|
-
- benchmark/sqlite-prepare.1.txt
|
41
36
|
- benchmark/sqlite-prepare.2.txt
|
37
|
+
- benchmark/sqlite-prepare.1.txt
|
38
|
+
- benchmark/sqlite-no-prepare.2.txt
|
39
|
+
- benchmark/sqlite-no-prepare.1.txt
|
40
|
+
- benchmark/bench.rb
|
42
41
|
- examples/run.rb
|
43
42
|
- examples/mysql_to_psql.rb
|
44
43
|
- examples/README
|
45
44
|
- doc/tutorial.txt
|
46
|
-
- doc/LICENSE
|
47
|
-
- doc/RELEASES
|
48
45
|
- doc/config.txt
|
46
|
+
- doc/RELEASES
|
47
|
+
- doc/LICENSE
|
49
48
|
- doc/AUTHORS
|
49
|
+
- doc/CHANGELOG.1
|
50
50
|
- lib/og
|
51
|
-
- lib/og.rb
|
52
51
|
- lib/vendor
|
53
|
-
- lib/og
|
54
|
-
- lib/og/entity.rb
|
55
|
-
- lib/og/relation.rb
|
56
|
-
- lib/og/relation
|
52
|
+
- lib/og.rb
|
57
53
|
- lib/og/mixin
|
54
|
+
- lib/og/relation
|
58
55
|
- lib/og/store
|
59
|
-
- lib/og/
|
60
|
-
- lib/og/errors.rb
|
61
|
-
- lib/og/store.rb
|
56
|
+
- lib/og/test
|
62
57
|
- lib/og/validation.rb
|
63
58
|
- lib/og/types.rb
|
64
|
-
- lib/og/test
|
65
59
|
- lib/og/test.rb
|
66
|
-
- lib/og/
|
67
|
-
- lib/og/relation
|
68
|
-
- lib/og/
|
60
|
+
- lib/og/store.rb
|
61
|
+
- lib/og/relation.rb
|
62
|
+
- lib/og/manager.rb
|
63
|
+
- lib/og/errors.rb
|
64
|
+
- lib/og/entity.rb
|
65
|
+
- lib/og/collection.rb
|
66
|
+
- lib/og/mixin/tree.rb
|
67
|
+
- lib/og/mixin/timestamped.rb
|
68
|
+
- lib/og/mixin/orderable.rb
|
69
|
+
- lib/og/mixin/optimistic_locking.rb
|
70
|
+
- lib/og/mixin/hierarchical.rb
|
71
|
+
- lib/og/mixin/taggable.rb
|
72
|
+
- lib/og/mixin/revisable.rb
|
69
73
|
- lib/og/relation/refers_to.rb
|
70
74
|
- lib/og/relation/many_to_many.rb
|
71
75
|
- lib/og/relation/joins_many.rb
|
72
|
-
- lib/og/
|
73
|
-
- lib/og/
|
74
|
-
- lib/og/
|
75
|
-
- lib/og/mixin/tree.rb
|
76
|
-
- lib/og/mixin/optimistic_locking.rb
|
77
|
-
- lib/og/store/filesys.rb
|
78
|
-
- lib/og/store/psql.rb
|
79
|
-
- lib/og/store/sql.rb
|
80
|
-
- lib/og/store/mysql.rb
|
76
|
+
- lib/og/relation/has_one.rb
|
77
|
+
- lib/og/relation/has_many.rb
|
78
|
+
- lib/og/relation/belongs_to.rb
|
81
79
|
- lib/og/store/sqlserver.rb
|
82
80
|
- lib/og/store/sqlite.rb
|
83
|
-
- lib/og/store/
|
81
|
+
- lib/og/store/sql.rb
|
82
|
+
- lib/og/store/psql.rb
|
83
|
+
- lib/og/store/mysql.rb
|
84
84
|
- lib/og/store/memory.rb
|
85
|
-
- lib/og/
|
85
|
+
- lib/og/store/kirby.rb
|
86
|
+
- lib/og/store/filesys.rb
|
86
87
|
- lib/og/test/testcase.rb
|
88
|
+
- lib/og/test/assertions.rb
|
87
89
|
- lib/vendor/mysql411.rb
|
88
90
|
- lib/vendor/mysql.rb
|
89
91
|
- lib/vendor/kirbybase.rb
|
90
92
|
- lib/vendor/README
|
91
93
|
- test/og
|
92
|
-
- test/og/store
|
93
94
|
- test/og/mixin
|
94
|
-
- test/og/
|
95
|
+
- test/og/store
|
95
96
|
- test/og/tc_types.rb
|
96
|
-
- test/og/tc_relation.rb
|
97
97
|
- test/og/tc_store.rb
|
98
|
-
- test/og/tc_polymorphic.rb
|
99
|
-
- test/og/tc_join.rb
|
100
98
|
- test/og/tc_select.rb
|
101
99
|
- test/og/tc_reverse.rb
|
100
|
+
- test/og/tc_relation.rb
|
101
|
+
- test/og/tc_polymorphic.rb
|
102
|
+
- test/og/tc_override.rb
|
102
103
|
- test/og/tc_multiple.rb
|
103
|
-
- test/og/
|
104
|
-
- test/og/
|
105
|
-
- test/og/mixin/tc_orderable.rb
|
104
|
+
- test/og/tc_join.rb
|
105
|
+
- test/og/tc_inheritance.rb
|
106
106
|
- test/og/mixin/tc_timestamped.rb
|
107
|
+
- test/og/mixin/tc_orderable.rb
|
107
108
|
- test/og/mixin/tc_optimistic_locking.rb
|
109
|
+
- test/og/mixin/tc_hierarchical.rb
|
110
|
+
- test/og/mixin/tc_taggable.rb
|
111
|
+
- test/og/store/tc_filesys.rb
|
108
112
|
test_files: []
|
109
113
|
rdoc_options:
|
110
114
|
- "--main"
|
@@ -129,5 +133,5 @@ dependencies:
|
|
129
133
|
-
|
130
134
|
- "="
|
131
135
|
- !ruby/object:Gem::Version
|
132
|
-
version: 0.
|
136
|
+
version: 0.23.0
|
133
137
|
version:
|