og 0.10.0 → 0.11.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/AUTHORS +4 -1
- data/ChangeLog +290 -7
- data/README.og +3 -4
- data/RELEASES.og +50 -0
- data/Rakefile +7 -7
- data/examples/og/run.rb +1 -1
- data/lib/glue/array.rb +14 -33
- data/lib/glue/hash.rb +32 -53
- data/lib/glue/pool.rb +9 -12
- data/lib/glue/property.rb +31 -9
- data/lib/og.rb +20 -12
- data/lib/og/adapter.rb +40 -13
- data/lib/og/adapters/filesys.rb +121 -0
- data/lib/og/adapters/mysql.rb +10 -5
- data/lib/og/adapters/oracle.rb +374 -0
- data/lib/og/adapters/psql.rb +10 -23
- data/lib/og/adapters/sqlite.rb +3 -3
- data/lib/og/backend.rb +2 -2
- data/lib/og/connection.rb +6 -6
- data/lib/og/database.rb +5 -5
- data/lib/og/enchant.rb +6 -2
- data/lib/og/meta.rb +56 -26
- data/lib/og/mock.rb +1 -1
- data/lib/og/typemacros.rb +23 -0
- data/test/og/tc_filesys.rb +83 -0
- data/test/og/tc_meta.rb +55 -0
- data/test/tc_og.rb +115 -36
- metadata +8 -4
- data/ChangeLog.1 +0 -2344
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ require 'rake/rdoctask'
|
|
6
6
|
require 'rake/testtask'
|
7
7
|
require 'rake/gempackagetask'
|
8
8
|
|
9
|
-
og = true
|
9
|
+
og = true
|
10
10
|
|
11
11
|
task :default => :package
|
12
12
|
|
@@ -14,7 +14,7 @@ task :default => :package
|
|
14
14
|
|
15
15
|
Rake::TestTask.new do |t|
|
16
16
|
t.libs << 'test'
|
17
|
-
t.test_files = FileList['test/**/tc*.rb'].exclude('**/tc*og*.rb')
|
17
|
+
t.test_files = FileList['test/**/tc*.rb'].exclude('**/tc*og*.rb').exclude('test/og/**/*')
|
18
18
|
t.verbose = true
|
19
19
|
end
|
20
20
|
|
@@ -30,8 +30,8 @@ end
|
|
30
30
|
|
31
31
|
Rake::RDocTask.new do |rd|
|
32
32
|
rd.main = 'README'
|
33
|
-
rd.rdoc_dir = 'rdoc'
|
34
|
-
rd.rdoc_files.include('README', 'INSTALL', 'lib/**/*.rb')
|
33
|
+
rd.rdoc_dir = 'doc/rdoc'
|
34
|
+
rd.rdoc_files.include('README', 'INSTALL', 'doc/og_config.txt', 'doc/og_tutorial.txt', 'lib/**/*.rb')
|
35
35
|
rd.options << '--all --inline-source'
|
36
36
|
end
|
37
37
|
|
@@ -91,11 +91,11 @@ spec = Gem::Specification.new do |s|
|
|
91
91
|
s.summary = 'Nitro Web Engine'
|
92
92
|
s.description =
|
93
93
|
'An efficient, multiparadigm and flexible platform for rapid ' +
|
94
|
-
'web application development. Implements a full development stack
|
95
|
-
|
96
|
-
|
94
|
+
'web application development. Implements a full development stack.'
|
95
|
+
|
97
96
|
# s.add_dependency 'postgres-pr', '>= 0.3.0'
|
98
97
|
# s.add_dependency 'postgres', '>= 0.7.1'
|
98
|
+
# s.add_dependency 'ParseTree', '>= 1.3.3'
|
99
99
|
s.add_dependency 'extensions', '>= 0.5'
|
100
100
|
# s.add_dependency 'sqlite3-ruby', '>= 1.0.0'
|
101
101
|
# s.add_dependency 'mysql', '>= 2.5.1'
|
data/examples/og/run.rb
CHANGED
data/lib/glue/array.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
# * George Moschovitis <gm@navel.gr>
|
2
2
|
# (c) 2002-2005 Navel, all rights reserved.
|
3
|
-
# $Id: array.rb
|
3
|
+
# $Id: array.rb 266 2005-02-28 14:50:48Z gmosx $
|
4
4
|
|
5
5
|
require 'sync'
|
6
6
|
|
7
7
|
module N
|
8
8
|
|
9
|
-
# A thread-safe array. We use a sync object instead of a
|
10
|
-
# because it is re-entrant.
|
11
|
-
#
|
12
|
-
# when reading
|
9
|
+
# A thread-safe array. We use a sync object instead of a
|
10
|
+
# mutex, because it is re-entrant. An exclusive lock is
|
11
|
+
# needed when writing, a shared lock IS NEEDED when reading.
|
13
12
|
|
14
13
|
class SafeArray < Array
|
15
14
|
|
@@ -18,61 +17,43 @@ class SafeArray < Array
|
|
18
17
|
# gmosx: delegator is not used.
|
19
18
|
|
20
19
|
def initialize(delegator = nil)
|
21
|
-
@sync =
|
20
|
+
@sync = Sync.new()
|
22
21
|
end
|
23
22
|
|
24
23
|
def << (value)
|
25
|
-
return @sync.synchronize(
|
26
|
-
super
|
27
|
-
}
|
24
|
+
return @sync.synchronize(Sync::SH) { super }
|
28
25
|
end
|
29
26
|
|
30
27
|
def delete_if(&block)
|
31
|
-
return @sync.synchronize(
|
32
|
-
super
|
33
|
-
}
|
28
|
+
return @sync.synchronize(Sync::SH) { super }
|
34
29
|
end
|
35
30
|
|
36
31
|
def [](key)
|
37
|
-
return @sync.synchronize(
|
38
|
-
super
|
39
|
-
}
|
32
|
+
return @sync.synchronize(Sync::SH) { super }
|
40
33
|
end
|
41
34
|
|
42
35
|
def []=(key, value)
|
43
|
-
return @sync.synchronize(
|
44
|
-
super
|
45
|
-
}
|
36
|
+
return @sync.synchronize(Sync::EX) { super }
|
46
37
|
end
|
47
38
|
|
48
39
|
def delete(key)
|
49
|
-
return @sync.synchronize(
|
50
|
-
super
|
51
|
-
}
|
40
|
+
return @sync.synchronize(Sync::EX) { super }
|
52
41
|
end
|
53
42
|
|
54
43
|
def clear
|
55
|
-
@sync.synchronize(
|
56
|
-
super
|
57
|
-
}
|
44
|
+
@sync.synchronize(Sync::EX) { super }
|
58
45
|
end
|
59
46
|
|
60
47
|
def size
|
61
|
-
return @sync.synchronize(
|
62
|
-
super
|
63
|
-
}
|
48
|
+
return @sync.synchronize(Sync::SH) { super }
|
64
49
|
end
|
65
50
|
|
66
51
|
def shift
|
67
|
-
return @sync.synchronize(::Sync::EX) {
|
68
|
-
super
|
69
|
-
}
|
52
|
+
return @sync.synchronize(::Sync::EX) { super }
|
70
53
|
end
|
71
54
|
|
72
55
|
def unshift(el)
|
73
|
-
return @sync.synchronize(::Sync::EX) {
|
74
|
-
super
|
75
|
-
}
|
56
|
+
return @sync.synchronize(::Sync::EX) { super }
|
76
57
|
end
|
77
58
|
|
78
59
|
end
|
data/lib/glue/hash.rb
CHANGED
@@ -1,22 +1,17 @@
|
|
1
|
-
# code:
|
2
1
|
# * George Moschovitis <gm@navel.gr>
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# $Id: hash.rb 202 2005-01-17 10:44:13Z gmosx $
|
2
|
+
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
+
# $Id: hash.rb 263 2005-02-23 13:45:08Z gmosx $
|
6
4
|
|
7
|
-
require
|
5
|
+
require 'sync'
|
8
6
|
|
9
|
-
module N
|
7
|
+
module N
|
10
8
|
|
11
|
-
# == SafeHash
|
12
|
-
#
|
13
9
|
# A thread-safe hash. We use a sync object instead of a mutex,
|
14
|
-
# because it is re-entrant.
|
15
|
-
#
|
16
|
-
# when reading
|
10
|
+
# because it is re-entrant. An exclusive lock is needed when
|
11
|
+
# writing, a shared lock IS NEEDED when reading
|
17
12
|
# uses the delegator pattern to allow for multiple
|
18
13
|
# implementations!
|
19
|
-
|
14
|
+
|
20
15
|
class SafeHash < Hash
|
21
16
|
attr :sync
|
22
17
|
|
@@ -27,63 +22,47 @@ class SafeHash < Hash
|
|
27
22
|
end
|
28
23
|
|
29
24
|
def [](key)
|
30
|
-
|
31
|
-
super
|
32
|
-
}
|
25
|
+
@sync.synchronize(::Sync::SH) { super }
|
33
26
|
end
|
34
27
|
|
35
28
|
def []=(key, value)
|
36
|
-
|
37
|
-
super
|
38
|
-
}
|
29
|
+
@sync.synchronize(::Sync::EX) { super }
|
39
30
|
end
|
40
31
|
|
41
32
|
def delete(key)
|
42
|
-
|
43
|
-
super
|
44
|
-
}
|
33
|
+
@sync.synchronize(::Sync::EX) { super }
|
45
34
|
end
|
46
35
|
|
47
36
|
def clear
|
48
|
-
@sync.synchronize(::Sync::EX) {
|
49
|
-
super
|
50
|
-
}
|
37
|
+
@sync.synchronize(::Sync::EX) { super }
|
51
38
|
end
|
52
39
|
|
53
40
|
def size
|
54
|
-
|
55
|
-
super
|
56
|
-
}
|
41
|
+
@sync.synchronize(::Sync::SH) { super }
|
57
42
|
end
|
58
43
|
|
59
44
|
def values
|
60
|
-
|
61
|
-
super
|
62
|
-
}
|
45
|
+
@sync.synchronize(::Sync::SH) { super }
|
63
46
|
end
|
64
47
|
|
65
48
|
def keys
|
66
|
-
|
67
|
-
super
|
68
|
-
}
|
49
|
+
@sync.synchronize(::Sync::SH) { super }
|
69
50
|
end
|
70
51
|
|
71
|
-
end
|
52
|
+
end
|
72
53
|
|
73
|
-
# == SafeHashDelegator
|
74
|
-
#
|
75
54
|
# A thread-safe hash. We use a sync object instead of a mutex,
|
76
|
-
# because it is re-entrant.
|
77
|
-
#
|
78
|
-
#
|
55
|
+
# because it is re-entrant. An exclusive lock is needed when
|
56
|
+
# writing, a shared lock IS NEEDED when reading.
|
57
|
+
#
|
58
|
+
# === Design
|
79
59
|
#
|
80
|
-
# Design:
|
81
60
|
# This class uses the delegator pattern. However we dont use rubys
|
82
61
|
# delegation facilities, they are more general and powerfull than we
|
83
62
|
# need here (and slower). Instead a custom (but simple) solution is
|
84
63
|
# used.
|
85
64
|
#
|
86
|
-
# Example
|
65
|
+
# === Example
|
87
66
|
#
|
88
67
|
# hash = SafeHashDelegator.new(Hash.new)
|
89
68
|
# hash = SafeHashDelegator.new(Hash.new)
|
@@ -96,20 +75,20 @@ class SafeHashDelegator < Hash
|
|
96
75
|
@sync = ::Sync.new
|
97
76
|
end
|
98
77
|
|
99
|
-
|
100
|
-
|
78
|
+
def [](key)
|
79
|
+
@sync.synchronize(::Sync::SH) {
|
101
80
|
@delegate[key]
|
102
81
|
}
|
103
|
-
|
82
|
+
end
|
104
83
|
|
105
|
-
|
106
|
-
|
84
|
+
def []=(key, value)
|
85
|
+
@sync.synchronize(::Sync::EX) {
|
107
86
|
@delegate[key] = value
|
108
87
|
}
|
109
|
-
|
88
|
+
end
|
110
89
|
|
111
90
|
def delete(key)
|
112
|
-
|
91
|
+
@sync.synchronize(::Sync::EX) {
|
113
92
|
@delegate.delete(key)
|
114
93
|
}
|
115
94
|
end
|
@@ -121,23 +100,23 @@ class SafeHashDelegator < Hash
|
|
121
100
|
end
|
122
101
|
|
123
102
|
def size
|
124
|
-
|
103
|
+
@sync.synchronize(::Sync::SH) {
|
125
104
|
@delegate.size()
|
126
105
|
}
|
127
106
|
end
|
128
107
|
|
129
108
|
def values
|
130
|
-
|
109
|
+
@sync.synchronize(::Sync::SH) {
|
131
110
|
@delegate.values()
|
132
111
|
}
|
133
112
|
end
|
134
113
|
|
135
114
|
def keys
|
136
|
-
|
115
|
+
@sync.synchronize(::Sync::SH) {
|
137
116
|
@delegate.keys()
|
138
117
|
}
|
139
118
|
end
|
140
119
|
|
141
|
-
end
|
120
|
+
end
|
142
121
|
|
143
|
-
end
|
122
|
+
end
|
data/lib/glue/pool.rb
CHANGED
@@ -1,21 +1,17 @@
|
|
1
|
-
# code:
|
2
1
|
# * George Moschovitis <gm@navel.gr>
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# $Id: pool.rb 202 2005-01-17 10:44:13Z gmosx $
|
2
|
+
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
+
# $Id: pool.rb 266 2005-02-28 14:50:48Z gmosx $
|
6
4
|
|
7
|
-
require
|
8
|
-
require
|
5
|
+
require 'thread'
|
6
|
+
require 'monitor'
|
9
7
|
|
10
8
|
module N
|
11
9
|
|
12
|
-
# = Pool
|
13
|
-
#
|
14
10
|
# Generalized object pool implementation. Implemented as a thread
|
15
11
|
# safe stack. Exclusive locking is needed both for push and pop.
|
16
12
|
#
|
17
13
|
# INVESTIGATE: Could use the SizedQueue/Queue.
|
18
|
-
|
14
|
+
|
19
15
|
class Pool < Array
|
20
16
|
include MonitorMixin
|
21
17
|
|
@@ -25,7 +21,7 @@ class Pool < Array
|
|
25
21
|
end
|
26
22
|
|
27
23
|
# Add, restore an object to the pool.
|
28
|
-
|
24
|
+
|
29
25
|
def push(obj)
|
30
26
|
synchronize do
|
31
27
|
super
|
@@ -34,7 +30,7 @@ class Pool < Array
|
|
34
30
|
end
|
35
31
|
|
36
32
|
# Obtain an object from the pool.
|
37
|
-
|
33
|
+
|
38
34
|
def pop
|
39
35
|
synchronize do
|
40
36
|
@cv.wait_while { empty? }
|
@@ -44,6 +40,7 @@ class Pool < Array
|
|
44
40
|
|
45
41
|
# Obtains an object, passes it to a block for processing
|
46
42
|
# and restores it to the pool.
|
43
|
+
|
47
44
|
def obtain
|
48
45
|
result = nil
|
49
46
|
|
@@ -60,4 +57,4 @@ class Pool < Array
|
|
60
57
|
|
61
58
|
end
|
62
59
|
|
63
|
-
end
|
60
|
+
end
|
data/lib/glue/property.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# * George Moschovitis <gm@navel.gr>
|
2
2
|
# * Michael Neumann <mneumann@ntecs.de>
|
3
3
|
# (c) 2004-2005 Navel, all rights reserved.
|
4
|
-
# $Id: property.rb
|
4
|
+
# $Id: property.rb 266 2005-02-28 14:50:48Z gmosx $
|
5
5
|
|
6
6
|
require 'glue/attribute'
|
7
7
|
require 'glue/array'
|
@@ -30,22 +30,35 @@ class Property
|
|
30
30
|
|
31
31
|
cattr_accessor :type_checking, false
|
32
32
|
|
33
|
-
#
|
33
|
+
# The symbol of the property.
|
34
34
|
|
35
35
|
attr_accessor :symbol
|
36
36
|
|
37
|
-
#
|
37
|
+
# The string representation of the symbol.
|
38
38
|
|
39
39
|
attr_accessor :name
|
40
40
|
|
41
|
-
#
|
41
|
+
# The class of the property.
|
42
42
|
|
43
43
|
attr_accessor :klass
|
44
|
-
|
45
|
-
#
|
44
|
+
|
45
|
+
# Additional metadata (like sql declaration, sql index, etc)
|
46
|
+
# Here is a list of predefined metadata:
|
47
|
+
#
|
48
|
+
# [+:reader+]
|
49
|
+
# create reader?
|
50
|
+
#
|
51
|
+
# [+:writer+]
|
52
|
+
# create writer?
|
53
|
+
#
|
54
|
+
# [+:sql_index+]
|
55
|
+
# create an sql index for the column this poperty maps to?
|
56
|
+
#
|
57
|
+
# You can use this mechanism to add your own, custom,
|
58
|
+
# metadata.
|
46
59
|
|
47
60
|
attr_accessor :meta
|
48
|
-
|
61
|
+
|
49
62
|
def initialize(symbol, klass, meta = {})
|
50
63
|
@symbol, @klass = symbol, klass
|
51
64
|
@meta = meta
|
@@ -124,6 +137,11 @@ module PropertyUtils
|
|
124
137
|
else
|
125
138
|
target.__props << prop
|
126
139
|
end
|
140
|
+
|
141
|
+
# Store the property in the :props_and_relations
|
142
|
+
# metadata array.
|
143
|
+
|
144
|
+
target.meta :props_and_relations, prop
|
127
145
|
|
128
146
|
# Precompile the property read/write methods
|
129
147
|
|
@@ -366,7 +384,7 @@ class Module
|
|
366
384
|
prop(klass, symbol, meta)
|
367
385
|
end
|
368
386
|
end
|
369
|
-
|
387
|
+
alias_method :property, :prop_accessor
|
370
388
|
|
371
389
|
# Attach metadata.
|
372
390
|
# Guard against duplicates, no need to keep order.
|
@@ -375,7 +393,11 @@ class Module
|
|
375
393
|
# gmosx: crappy implementation, recode.
|
376
394
|
#++
|
377
395
|
|
378
|
-
def meta(key, val)
|
396
|
+
def meta(key, *val)
|
397
|
+
val = val.first if val.size == 1
|
398
|
+
|
399
|
+
N::PropertyUtils.enchant(self)
|
400
|
+
|
379
401
|
self.module_eval %{
|
380
402
|
@@__meta[key] ||= []
|
381
403
|
@@__meta[key].delete_if { |v| val == v }
|
data/lib/og.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# * George Moschovitis <gm@navel.gr>
|
2
2
|
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: og.rb
|
3
|
+
# $Id: og.rb 266 2005-02-28 14:50:48Z gmosx $
|
4
4
|
|
5
5
|
require 'glue'
|
6
6
|
require 'glue/logger'
|
@@ -89,7 +89,7 @@ require 'glue/validation'
|
|
89
89
|
# * Deserialize to OpenStruct.
|
90
90
|
# * Better documentation.
|
91
91
|
|
92
|
-
|
92
|
+
module Og
|
93
93
|
|
94
94
|
# The name.
|
95
95
|
|
@@ -97,7 +97,7 @@ class Og
|
|
97
97
|
|
98
98
|
# The version.
|
99
99
|
|
100
|
-
Version = '0.
|
100
|
+
Version = '0.11.0'
|
101
101
|
|
102
102
|
# Library path.
|
103
103
|
|
@@ -106,37 +106,45 @@ class Og
|
|
106
106
|
# If true, only allow reading from the database. Usefull
|
107
107
|
# for maintainance.
|
108
108
|
|
109
|
-
|
109
|
+
mattr_accessor :read_only_mode, false
|
110
110
|
|
111
111
|
# If true, the library automatically 'enchants' managed classes.
|
112
112
|
# In enchant mode, special db aware methods are added to
|
113
113
|
# managed classes and instances.
|
114
|
+
# If false, Og enchants only classes that define properties.
|
114
115
|
|
115
|
-
|
116
|
+
mattr_accessor :enchant_managed_classes, true
|
116
117
|
|
117
118
|
# If true, use Ruby's advanced introspection capabilities to
|
118
119
|
# automatically manage classes tha define properties.
|
119
120
|
|
120
|
-
|
121
|
+
mattr_accessor :auto_manage_classes, true
|
121
122
|
|
122
123
|
# If true, automatically include the Og meta-language into Module.
|
123
|
-
#
|
124
|
-
#
|
125
|
-
# However if you include a prop_accessor or a managed Mixin in your
|
124
|
+
# If false, the polution of the Module object is avoided. However
|
125
|
+
# if you include a prop_accessor or a managed Mixin in your
|
126
126
|
# object MetaLanguage gets automatically extended in the class.
|
127
127
|
|
128
|
-
|
128
|
+
mattr_accessor :include_meta_language, true
|
129
129
|
|
130
130
|
# Attach the following prefix to all generated SQL table names.
|
131
131
|
# Usefull on hosting scenarios where you have to run multiple
|
132
132
|
# web applications/sites on a single database.
|
133
133
|
|
134
|
-
|
134
|
+
mattr_accessor :table_prefix, nil
|
135
135
|
|
136
|
+
# If true, Og tries to create/update the schema in the
|
137
|
+
# data store. For production/live environments set this to false
|
138
|
+
# and only set to true when the object model is upadated.
|
139
|
+
# For debug/development environments this should stay true
|
140
|
+
# for convienience.
|
141
|
+
|
142
|
+
mattr_accessor :create_schema, true
|
143
|
+
|
136
144
|
# The active database. Og allows you to access multiple
|
137
145
|
# databases from a single application.
|
138
146
|
|
139
|
-
|
147
|
+
mattr_accessor :db
|
140
148
|
|
141
149
|
# Set the active database.
|
142
150
|
|