nitro 0.8.0 → 0.9.3
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 +3 -4
- data/ChangeLog +418 -0
- data/LICENSE +1 -1
- data/README +157 -89
- data/RELEASES +50 -0
- data/Rakefile +5 -7
- data/benchmark/nitro/bench.rb +5 -0
- data/benchmark/nitro/simple-webrick-n-200.txt +44 -0
- data/benchmark/nitro/static-webrick-n-200.txt +43 -0
- data/benchmark/nitro/tiny-lhttpd-n-200-c-5.txt +43 -0
- data/benchmark/nitro/tiny-webrick-n-200-c-5.txt +44 -0
- data/benchmark/nitro/tiny-webrick-n-200.txt +44 -0
- data/benchmark/nitro/tiny2-webrick-n-200.txt +44 -0
- data/{lib/nitro/server/cluster.rb → bin/cluster} +26 -30
- data/bin/proto/README +2 -2
- data/bin/proto/{apache.conf → conf/apache.conf} +0 -0
- data/bin/proto/conf/app.conf.rb +22 -0
- data/bin/proto/conf/lhttpd.conf +236 -0
- data/bin/proto/ctl +4 -0
- data/bin/proto/lib/README +5 -0
- data/bin/proto/log/README +3 -0
- data/bin/proto/root/fcgi.rb +6 -0
- data/bin/proto/root/index.xhtml +65 -7
- data/bin/proto/root/m/nitro.png +0 -0
- data/examples/blog/README +7 -5
- data/examples/blog/{apache.conf → conf/apache.conf} +0 -0
- data/examples/blog/conf/app.conf.rb +56 -0
- data/examples/blog/conf/lhttpd.conf +236 -0
- data/examples/blog/ctl +4 -0
- data/examples/blog/lib/blog.rb +11 -136
- data/examples/blog/lib/blog/controller.rb +99 -0
- data/examples/blog/lib/blog/model.rb +39 -0
- data/examples/blog/log/README +3 -0
- data/examples/blog/root/comments.xhtml +2 -2
- data/examples/blog/root/fcgi.rb +6 -0
- data/examples/blog/root/index.xhtml +4 -5
- data/examples/blog/root/login.xhtml +2 -2
- data/examples/blog/root/style.xsl +9 -9
- data/examples/blog/root/view_entry.xhtml +2 -2
- data/examples/flash/conf/app.conf.rb +23 -0
- data/examples/flash/ctl +4 -0
- data/examples/flash/log/README +3 -0
- data/examples/flash/root/index.xhtml +0 -9
- data/examples/flash/root/show_inline_text.xhtml +10 -5
- data/examples/no_xsl_blog/README +12 -0
- data/examples/no_xsl_blog/conf/apache.conf +0 -0
- data/examples/no_xsl_blog/conf/app.conf.rb +57 -0
- data/examples/no_xsl_blog/conf/lhttpd.conf +236 -0
- data/examples/no_xsl_blog/ctl +4 -0
- data/examples/no_xsl_blog/lib/blog.rb +20 -0
- data/examples/no_xsl_blog/lib/blog/controller.rb +102 -0
- data/examples/no_xsl_blog/lib/blog/model.rb +39 -0
- data/examples/no_xsl_blog/lib/blog/template.rb +134 -0
- data/examples/no_xsl_blog/log/README +3 -0
- data/examples/no_xsl_blog/root/comments.xhtml +41 -0
- data/examples/no_xsl_blog/root/entry_form.xhtml +22 -0
- data/examples/no_xsl_blog/root/fcgi.rb +6 -0
- data/examples/no_xsl_blog/root/index.xhtml +39 -0
- data/examples/no_xsl_blog/root/login.xhtml +21 -0
- data/examples/no_xsl_blog/root/m/bubbles.gif +0 -0
- data/examples/no_xsl_blog/root/m/comments_curve.gif +0 -0
- data/examples/no_xsl_blog/root/m/down.gif +0 -0
- data/examples/no_xsl_blog/root/m/footer_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/garrow.gif +0 -0
- data/examples/no_xsl_blog/root/m/gbull.gif +0 -0
- data/examples/no_xsl_blog/root/m/grbull.gif +0 -0
- data/examples/no_xsl_blog/root/m/h1_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/header_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/nitro.gif +0 -0
- data/examples/no_xsl_blog/root/m/obull.gif +0 -0
- data/examples/no_xsl_blog/root/m/page_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/rss.gif +0 -0
- data/examples/no_xsl_blog/root/m/side_title_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/sidebar_bg.gif +0 -0
- data/examples/no_xsl_blog/root/recent_posts.xhtml +14 -0
- data/examples/no_xsl_blog/root/style.css +301 -0
- data/examples/no_xsl_blog/root/view_entry.xhtml +25 -0
- data/examples/no_xsl_blog/root/view_entry.xml +12 -0
- data/examples/og/run.rb +2 -2
- data/examples/tiny/README +2 -2
- data/examples/tiny/conf/apache.conf +5 -0
- data/examples/tiny/conf/app.conf.rb +21 -0
- data/examples/tiny/conf/lhttpd.conf +236 -0
- data/examples/tiny/ctl +4 -0
- data/examples/tiny/log/README +3 -0
- data/examples/tiny/root/fcgi.rb +6 -0
- data/examples/tiny/root/index.xhtml +7 -4
- data/examples/tiny/root/nitro.png +0 -0
- data/lib/glue.rb +13 -9
- data/lib/glue/array.rb +1 -1
- data/lib/glue/cache.rb +1 -1
- data/lib/glue/flexob.rb +12 -0
- data/lib/glue/hash.rb +1 -1
- data/lib/glue/inflector.rb +2 -2
- data/lib/glue/logger.rb +4 -8
- data/lib/glue/misc.rb +14 -0
- data/lib/glue/number.rb +1 -1
- data/lib/glue/object.rb +26 -0
- data/lib/glue/pool.rb +1 -1
- data/lib/glue/property.rb +84 -91
- data/lib/glue/string.rb +1 -1
- data/lib/glue/time.rb +1 -1
- data/lib/glue/validation.rb +1 -1
- data/lib/nitro.rb +18 -6
- data/lib/nitro/adaptors/cgi.rb +291 -0
- data/lib/nitro/adaptors/fastcgi.rb +42 -0
- data/lib/nitro/adaptors/runner.rb +123 -0
- data/lib/nitro/adaptors/webrick.rb +110 -0
- data/lib/nitro/buffering.rb +43 -0
- data/lib/nitro/builders/form.rb +1 -1
- data/lib/nitro/builders/rss.rb +1 -1
- data/{bin → lib/nitro}/cluster.rb +26 -30
- data/lib/nitro/context.rb +82 -0
- data/lib/nitro/controller.rb +50 -0
- data/lib/nitro/cookie.rb +46 -0
- data/lib/nitro/dispatcher.rb +105 -0
- data/lib/nitro/filters.rb +9 -10
- data/lib/nitro/localization.rb +42 -0
- data/lib/nitro/mail.rb +11 -14
- data/lib/nitro/render.rb +275 -0
- data/lib/nitro/request.rb +128 -0
- data/lib/nitro/response.rb +38 -0
- data/lib/nitro/scaffold.rb +11 -11
- data/lib/nitro/session.rb +84 -0
- data/lib/nitro/{server/shaders.rb → shaders.rb} +56 -36
- data/lib/nitro/ui/pager.rb +23 -26
- data/lib/nitro/{sitemap.rb → ui/sitemap.rb} +4 -12
- data/lib/nitro/uri.rb +1 -1
- data/lib/nitro/version.rb +10 -8
- data/lib/og.rb +66 -65
- data/lib/og/backend.rb +1 -1
- data/lib/og/backends/mysql.rb +48 -52
- data/lib/og/backends/psql.rb +34 -37
- data/lib/og/connection.rb +15 -15
- data/lib/og/enchant.rb +16 -9
- data/lib/og/meta.rb +127 -54
- data/lib/og/mock.rb +18 -18
- data/lib/og/version.rb +6 -4
- data/lib/parts/content.rb +4 -8
- data/test/glue/tc_logger.rb +3 -0
- data/test/glue/tc_property.rb +19 -3
- data/test/nitro/adaptors/tc_cgi.rb +63 -0
- data/test/nitro/adaptors/tc_webrick.rb +15 -0
- data/test/nitro/builders/tc_xml.rb +2 -2
- data/test/nitro/tc_context.rb +13 -0
- data/test/nitro/tc_controller.rb +47 -0
- data/test/nitro/tc_dispatcher.rb +64 -0
- data/test/nitro/tc_session.rb +20 -0
- data/test/nitro/{tc_sitemap.rb → ui/tc_sitemap.rb} +1 -1
- data/test/root/blog/list.xhtml +6 -0
- data/test/tc_og.rb +41 -4
- metadata +115 -59
- data/bin/proto/app.rb +0 -20
- data/bin/proto/config.rb +0 -77
- data/examples/blog/app.rb +0 -21
- data/examples/blog/config.rb +0 -95
- data/examples/blog/env.rb +0 -22
- data/examples/flash/README +0 -34
- data/examples/flash/app.rb +0 -20
- data/examples/flash/config.rb +0 -38
- data/examples/flash/lib/flash.rb +0 -40
- data/examples/flash/tmp.swf +0 -0
- data/examples/tiny/app.rb +0 -19
- data/examples/tiny/config.rb +0 -29
- data/examples/tiny/root/nitro-small.png +0 -0
- data/lib/nitro/application.rb +0 -217
- data/lib/nitro/config.rb +0 -128
- data/lib/nitro/events.rb +0 -122
- data/lib/nitro/html.rb +0 -151
- data/lib/nitro/http.rb +0 -102
- data/lib/nitro/l10n.rb +0 -30
- data/lib/nitro/server.rb +0 -59
- data/lib/nitro/server/appserver.rb +0 -67
- data/lib/nitro/server/cookie.rb +0 -87
- data/lib/nitro/server/dispatcher.rb +0 -62
- data/lib/nitro/server/filters.rb +0 -75
- data/lib/nitro/server/filters/autologin.rb +0 -51
- data/lib/nitro/server/fragment.rb +0 -70
- data/lib/nitro/server/handlers.rb +0 -127
- data/lib/nitro/server/render.rb +0 -426
- data/lib/nitro/server/request.rb +0 -658
- data/lib/nitro/server/requestpart.rb +0 -54
- data/lib/nitro/server/script.rb +0 -387
- data/lib/nitro/server/server.rb +0 -57
- data/lib/nitro/server/session.rb +0 -220
- data/lib/nitro/server/user.rb +0 -46
- data/lib/nitro/server/webrick.rb +0 -180
- data/lib/nitro/service.rb +0 -26
- data/lib/xsl/ui.xsl +0 -51
- data/lib/xsl/xforms.xsl +0 -28
- data/test/nitro/server/tc_cookie.rb +0 -34
- data/test/nitro/server/tc_filters.rb +0 -38
- data/test/nitro/server/tc_request.rb +0 -70
- data/test/nitro/server/tc_requestpart.rb +0 -28
- data/test/nitro/server/tc_session.rb +0 -34
- data/test/nitro/tc_events.rb +0 -44
- data/test/nitro/tc_html.rb +0 -79
- data/test/nitro/tc_http.rb +0 -18
data/lib/og/connection.rb
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
|
|
1
|
+
#--
|
|
2
|
+
# George Moschovitis <gm@navel.gr>
|
|
3
|
+
# (c) 2004-2005 Navel, all rights reserved.
|
|
4
|
+
# $Id: connection.rb 248 2005-01-31 13:38:34Z gmosx $
|
|
5
|
+
#++
|
|
6
6
|
|
|
7
7
|
class Og;
|
|
8
8
|
|
|
9
|
-
require
|
|
10
|
-
require
|
|
11
|
-
require
|
|
9
|
+
require 'glue/property'
|
|
10
|
+
require 'glue/array'
|
|
11
|
+
require 'glue/time'
|
|
12
12
|
|
|
13
|
-
# = Connection
|
|
14
|
-
#
|
|
15
13
|
# A Connection to the Database. This file defines the skeleton
|
|
16
14
|
# functionality. A backend specific implementation file (driver)
|
|
17
15
|
# implements all methods.
|
|
@@ -20,20 +18,23 @@ require "glue/time"
|
|
|
20
18
|
#
|
|
21
19
|
# - support caching.
|
|
22
20
|
# - support prepared statements.
|
|
23
|
-
|
|
21
|
+
|
|
24
22
|
class Connection
|
|
25
23
|
# The frontend (Og) contains useful strucutres.
|
|
24
|
+
|
|
26
25
|
attr_reader :og
|
|
27
26
|
|
|
28
27
|
# The backend
|
|
28
|
+
|
|
29
29
|
attr_reader :db
|
|
30
30
|
|
|
31
31
|
# If set to true, the select methods deserialize the
|
|
32
32
|
# resultset to create entities.
|
|
33
|
+
|
|
33
34
|
attr_accessor :deserialize
|
|
34
35
|
|
|
35
36
|
# Initialize a connection to the database
|
|
36
|
-
|
|
37
|
+
|
|
37
38
|
def initialize(og)
|
|
38
39
|
@og = og
|
|
39
40
|
@db = @og.config[:backend].new(@og.config)
|
|
@@ -189,9 +190,8 @@ class Connection
|
|
|
189
190
|
# TODO: implement this as stored procedure? naaah.
|
|
190
191
|
transaction do |tx|
|
|
191
192
|
tx.exec "DELETE FROM #{klass::DBTABLE} WHERE oid=#{oid}"
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
klass.og_descendants.each do |dclass, linkback|
|
|
193
|
+
if cascade and klass.__meta.include?(:has)
|
|
194
|
+
klass.__meta[:has].each do |dclass, linkback|
|
|
195
195
|
tx.exec "DELETE FROM #{dclass::DBTABLE} WHERE #{linkback}=#{oid}"
|
|
196
196
|
end
|
|
197
197
|
end
|
data/lib/og/enchant.rb
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
# code:
|
|
2
1
|
# * George Moschovitis <gm@navel.gr>
|
|
3
|
-
#
|
|
4
|
-
# (c) 2004 Navel, all rights reserved.
|
|
2
|
+
# (c) 2004-2005 Navel, all rights reserved.
|
|
5
3
|
# $Id: meta.rb 198 2004-12-22 11:26:59Z gmosx $
|
|
6
4
|
|
|
7
5
|
class Og
|
|
8
6
|
|
|
9
7
|
module Enchant
|
|
10
8
|
|
|
11
|
-
# Enchant a managed class. Add useful DB related methods
|
|
12
|
-
# class and its instances.
|
|
13
|
-
|
|
9
|
+
# Enchant a managed class. Add useful DB related methods
|
|
10
|
+
# to the class and its instances.
|
|
11
|
+
|
|
14
12
|
def enchant(klass)
|
|
15
13
|
klass.module_eval <<-"end_eval", __FILE__, __LINE__
|
|
16
|
-
def self.create(*params)
|
|
17
|
-
obj = #{klass}.new(*params)
|
|
14
|
+
def self.create(*params, &block)
|
|
15
|
+
obj = #{klass}.new(*params, &block)
|
|
18
16
|
obj.save!
|
|
19
17
|
end
|
|
20
18
|
|
|
@@ -26,6 +24,10 @@ module Enchant
|
|
|
26
24
|
Og.db.load(oid_or_name, #{klass})
|
|
27
25
|
end
|
|
28
26
|
|
|
27
|
+
def self.get(oid_or_name)
|
|
28
|
+
Og.db.load(oid_or_name, #{klass})
|
|
29
|
+
end
|
|
30
|
+
|
|
29
31
|
def self.[](oid_or_name)
|
|
30
32
|
Og.db.load(oid_or_name, #{klass})
|
|
31
33
|
end
|
|
@@ -57,6 +59,11 @@ module Enchant
|
|
|
57
59
|
def self.delete(obj_or_oid)
|
|
58
60
|
Og.db.delete(obj_or_oid, #{klass})
|
|
59
61
|
end
|
|
62
|
+
|
|
63
|
+
def each(&block)
|
|
64
|
+
all.each(&block)
|
|
65
|
+
end
|
|
66
|
+
include Enumerable
|
|
60
67
|
|
|
61
68
|
def save
|
|
62
69
|
Og.db << self
|
|
@@ -77,4 +84,4 @@ module Enchant
|
|
|
77
84
|
|
|
78
85
|
end
|
|
79
86
|
|
|
80
|
-
end
|
|
87
|
+
end
|
data/lib/og/meta.rb
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
# code:
|
|
2
1
|
# * George Moschovitis <gm@navel.gr>
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
# $Id: meta.rb 198 2004-12-22 11:26:59Z gmosx $
|
|
2
|
+
# (c) 2004-2005 Navel, all rights reserved.
|
|
3
|
+
# $Id: meta.rb 248 2005-01-31 13:38:34Z gmosx $
|
|
6
4
|
|
|
7
5
|
require 'og/backend'
|
|
8
6
|
require 'glue/inflector'
|
|
@@ -12,18 +10,42 @@ class Og
|
|
|
12
10
|
# = MetaUtils
|
|
13
11
|
#
|
|
14
12
|
# Some useful meta-language utilities.
|
|
15
|
-
|
|
13
|
+
|
|
16
14
|
module MetaUtils # :nodoc: all
|
|
17
15
|
|
|
18
|
-
#
|
|
16
|
+
# Convert the klass to a string representation
|
|
19
17
|
# The leading module if available is removed.
|
|
20
18
|
#--
|
|
21
19
|
# gmosx, FIXME: unify with the ogutils.encode method?
|
|
22
20
|
#++
|
|
21
|
+
|
|
23
22
|
def self.expand(klass)
|
|
24
23
|
return klass.name.gsub(/^.*::/, '').gsub(/::/, '_').downcase
|
|
25
24
|
end
|
|
26
25
|
|
|
26
|
+
# Infer the target klass for a relation. When defining
|
|
27
|
+
# relations, tha target class is typically given. Some times
|
|
28
|
+
# in order to avoid forward declarations a symbol is given instead
|
|
29
|
+
# of a class. Other times on class is given at all, and
|
|
30
|
+
# the inflection mechanism is used to infer the class name.
|
|
31
|
+
|
|
32
|
+
def self.resolve_class(name, klass)
|
|
33
|
+
klass ||= N::Inflector.camelize(name)
|
|
34
|
+
|
|
35
|
+
return klass if klass.is_a?(Class)
|
|
36
|
+
|
|
37
|
+
unless klass.is_a?(String) or klass.is_a?(Symbol)
|
|
38
|
+
raise 'Invalid class definition'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
unless Object.const_get(klass.intern)
|
|
42
|
+
# Forward declaration.
|
|
43
|
+
Object.class_eval("class #{klass}; end")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
return Object.const_get(klass)
|
|
47
|
+
end
|
|
48
|
+
|
|
27
49
|
end
|
|
28
50
|
|
|
29
51
|
# = MetaLanguage
|
|
@@ -33,11 +55,12 @@ end
|
|
|
33
55
|
# from the excellent ActiveRecord library.
|
|
34
56
|
#
|
|
35
57
|
# Many more useful relations will be available soon.
|
|
36
|
-
|
|
58
|
+
|
|
37
59
|
module MetaLanguage
|
|
38
60
|
|
|
39
|
-
# Defines an SQL index.
|
|
40
|
-
#
|
|
61
|
+
# Defines an SQL index. Useful for defining indiced
|
|
62
|
+
# over multiple columns.
|
|
63
|
+
|
|
41
64
|
def sql_index(index, options = {})
|
|
42
65
|
meta :sql_index, [index, options]
|
|
43
66
|
end
|
|
@@ -56,12 +79,14 @@ module MetaLanguage
|
|
|
56
79
|
# prop_accessor Fixnum, :parent_oid
|
|
57
80
|
# def parent; ... end
|
|
58
81
|
# def parent=(obj_or_oid); ... end
|
|
59
|
-
|
|
82
|
+
|
|
60
83
|
def belongs_to(name, klass, options = {})
|
|
61
84
|
prop_eval = "prop_accessor Fixnum, :#{name}_oid"
|
|
62
85
|
prop_eval << ", :sql => '#{options[:sql]}'" if options[:sql]
|
|
63
86
|
prop_eval << ", :extra_sql => '#{options[:extra_sql]}'" if options[:extra_sql]
|
|
64
87
|
|
|
88
|
+
meta :belongs_to, klass
|
|
89
|
+
|
|
65
90
|
module_eval %{
|
|
66
91
|
#{prop_eval}
|
|
67
92
|
|
|
@@ -81,31 +106,31 @@ module MetaLanguage
|
|
|
81
106
|
# Example:
|
|
82
107
|
#
|
|
83
108
|
# class MyObject
|
|
84
|
-
# has_one
|
|
109
|
+
# has_one :child, TheClass
|
|
110
|
+
# has_one :article
|
|
85
111
|
# end
|
|
86
112
|
#
|
|
87
113
|
# creates the code:
|
|
88
114
|
#
|
|
89
115
|
# ...
|
|
90
|
-
|
|
91
|
-
def has_one(name, klass, options = {})
|
|
116
|
+
|
|
117
|
+
def has_one(name, klass = nil, options = {})
|
|
118
|
+
|
|
92
119
|
# linkback is the property of the child object that 'links back'
|
|
93
120
|
# to this object.
|
|
121
|
+
|
|
94
122
|
linkback = options[:linkback] || "#{MetaUtils.expand(self)}_oid"
|
|
95
123
|
|
|
124
|
+
meta :has, [klass, linkback]
|
|
125
|
+
|
|
96
126
|
module_eval %{
|
|
97
|
-
@@og_descendants ||= {}
|
|
98
|
-
@@og_descendants[#{klass}] = :#{linkback}
|
|
99
|
-
|
|
100
|
-
unless defined?(og_descendants)
|
|
101
|
-
def self.og_descendants
|
|
102
|
-
@@og_descendants
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
127
|
def #{name}(extrasql = nil)
|
|
107
|
-
Og.db.select_one("SELECT * FROM #{
|
|
128
|
+
Og.db.select_one("SELECT * FROM #{Backend.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}", #{klass})
|
|
108
129
|
end
|
|
130
|
+
|
|
131
|
+
def delete_#{name}(extrasql = nil)
|
|
132
|
+
Og.db.exec("DELETE FROM #{Backend.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}")
|
|
133
|
+
end
|
|
109
134
|
}
|
|
110
135
|
end
|
|
111
136
|
|
|
@@ -121,36 +146,37 @@ module MetaLanguage
|
|
|
121
146
|
# creates the code:
|
|
122
147
|
#
|
|
123
148
|
# def children; ... end
|
|
124
|
-
|
|
149
|
+
|
|
125
150
|
def has_many(name, klass, options = {})
|
|
126
151
|
name_s = N::Inflector.singularize(name.to_s)
|
|
127
152
|
|
|
128
153
|
# linkback is the property of the child object that 'links back'
|
|
129
154
|
# to this object.
|
|
155
|
+
|
|
130
156
|
linkback = options[:linkback] || "#{MetaUtils.expand(self)}_oid"
|
|
131
157
|
|
|
158
|
+
# keep belongs to metadata, useful for
|
|
159
|
+
# reflection/scaffolding.
|
|
160
|
+
|
|
161
|
+
meta :has, [klass, linkback]
|
|
162
|
+
|
|
132
163
|
module_eval %{
|
|
133
|
-
@@og_descendants ||= {}
|
|
134
|
-
@@og_descendants[#{klass}] = :#{linkback}
|
|
135
|
-
|
|
136
|
-
unless defined?(og_descendants)
|
|
137
|
-
def self.og_descendants
|
|
138
|
-
@@og_descendants
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
164
|
def #{name}(extrasql = nil)
|
|
143
|
-
Og.db.select("SELECT * FROM #{
|
|
165
|
+
Og.db.select("SELECT * FROM #{Backend.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}", #{klass})
|
|
144
166
|
end
|
|
145
167
|
|
|
146
168
|
def #{name}_count(extrasql = nil)
|
|
147
|
-
Og.db.count("SELECT COUNT(*) FROM #{
|
|
169
|
+
Og.db.count("SELECT COUNT(*) FROM #{Backend.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}")
|
|
148
170
|
end
|
|
149
171
|
|
|
150
172
|
def add_#{name_s}(obj, extra = nil)
|
|
151
173
|
obj.#{linkback} = @oid
|
|
152
174
|
obj.save!
|
|
153
175
|
end
|
|
176
|
+
|
|
177
|
+
def delete_all_#{name}(extrasql = nil)
|
|
178
|
+
Og.db.exec("DELETE FROM #{Backend.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}")
|
|
179
|
+
end
|
|
154
180
|
}
|
|
155
181
|
end
|
|
156
182
|
|
|
@@ -173,10 +199,10 @@ module MetaLanguage
|
|
|
173
199
|
#
|
|
174
200
|
# category.articles
|
|
175
201
|
# ...
|
|
176
|
-
#
|
|
177
202
|
#--
|
|
178
203
|
# FIXME: make more compatible with other enchant methods.
|
|
179
204
|
#++
|
|
205
|
+
|
|
180
206
|
def many_to_many(name, klass, options = {})
|
|
181
207
|
list_o = name.to_s
|
|
182
208
|
prop_o = N::Inflector.singularize(list_o)
|
|
@@ -185,36 +211,38 @@ module MetaLanguage
|
|
|
185
211
|
|
|
186
212
|
# exit if the class is allready indirectly 'enchanted' from the
|
|
187
213
|
# other class of the many_to_many relation.
|
|
214
|
+
|
|
188
215
|
return if self.respond_to?(prop_m)
|
|
189
216
|
|
|
190
217
|
# Add some metadata to the class to allow for automatic join table
|
|
191
218
|
# calculation.
|
|
219
|
+
|
|
192
220
|
meta :sql_join, [klass, options]
|
|
193
221
|
|
|
194
|
-
|
|
222
|
+
meta :many_to_many, klass
|
|
223
|
+
klass.meta :many_to_many, self
|
|
195
224
|
|
|
196
225
|
# enchant this class
|
|
197
226
|
|
|
198
227
|
module_eval %{
|
|
199
228
|
def #{list_o}(extrasql = nil)
|
|
200
|
-
Og.db.select("SELECT d.* FROM #{
|
|
229
|
+
Og.db.select("SELECT d.* FROM #{Backend.table(klass)} AS d, #{Backend.join_table(self, klass)} AS j WHERE j.key1=\#\@oid AND j.key2=d.oid \#\{extrasql\}", #{klass})
|
|
201
230
|
end
|
|
202
231
|
|
|
203
232
|
def #{list_o}_count(extrasql = nil)
|
|
204
|
-
Og.db.select("SELECT COUNT(*) FROM #{
|
|
233
|
+
Og.db.select("SELECT COUNT(*) FROM #{Backend.table(klass)} AS d, #{Backend.join_table(self, klass)} AS j WHERE j.key1=\#\@oid AND j.key2=d.oid \#\{extrasql\}", #{klass})
|
|
205
234
|
end
|
|
206
235
|
|
|
207
236
|
def add_#{prop_o}(obj, extra = nil)
|
|
208
|
-
Og.db.exec("INSERT INTO #{
|
|
237
|
+
Og.db.exec("INSERT INTO #{Backend.join_table(self, klass)} (key1, key2) VALUES (\#\@oid, \#\{obj.oid\})")
|
|
209
238
|
end
|
|
210
239
|
|
|
211
|
-
def
|
|
212
|
-
Og.db.exec("DELETE FROM #{
|
|
240
|
+
def delete_#{prop_o}(obj_or_oid, extra = nil)
|
|
241
|
+
Og.db.exec("DELETE FROM #{Backend.join_table(self, klass)} WHERE key2=\#\{obj_or_oid.to_i\}")
|
|
213
242
|
end
|
|
214
|
-
alias_method :delete_#{prop_o}, :del_#{prop_o}
|
|
215
243
|
|
|
216
244
|
def clear_#{list_o}
|
|
217
|
-
Og.db.exec("DELETE FROM #{
|
|
245
|
+
Og.db.exec("DELETE FROM #{Backend.join_table(self, klass)} WHERE key1=\#\@oid")
|
|
218
246
|
end
|
|
219
247
|
}
|
|
220
248
|
|
|
@@ -222,40 +250,85 @@ module MetaLanguage
|
|
|
222
250
|
|
|
223
251
|
klass.module_eval %{
|
|
224
252
|
def #{list_m}(extrasql = nil)
|
|
225
|
-
Og.db.select("SELECT s.* FROM #{
|
|
253
|
+
Og.db.select("SELECT s.* FROM #{Backend.table(self)} AS s, #{Backend.join_table(self, klass)} AS j WHERE j.key2=\#\@oid AND j.key1=s.oid \#\{extrasql\}", #{self})
|
|
226
254
|
end
|
|
227
255
|
|
|
228
256
|
def #{list_m}_count(extrasql = nil)
|
|
229
|
-
Og.db.select("SELECT COUNT(*) FROM #{
|
|
257
|
+
Og.db.select("SELECT COUNT(*) FROM #{Backend.table(self)} AS s, #{Backend.join_table(self, klass)} AS j WHERE j.key2=\#\@oid AND j.key1=s.oid \#\{extrasql\}", #{self})
|
|
230
258
|
end
|
|
231
259
|
|
|
232
260
|
def add_#{prop_m}(obj, extra = nil)
|
|
233
|
-
Og.db.exec("INSERT INTO #{
|
|
261
|
+
Og.db.exec("INSERT INTO #{Backend.join_table(self, klass)} (key1, key2) VALUES (\#\{obj.oid\}, \#\@oid)")
|
|
234
262
|
end
|
|
235
263
|
|
|
236
|
-
def
|
|
237
|
-
Og.db.exec("DELETE FROM #{
|
|
264
|
+
def delete_#{prop_m}(obj_or_oid, extra = nil)
|
|
265
|
+
Og.db.exec("DELETE FROM #{Backend.join_table(self, klass)} WHERE key1=\#\{obj_or_oid.to_i\}")
|
|
238
266
|
end
|
|
239
|
-
alias_method :delete_#{prop_m}, :del_#{prop_m}
|
|
240
267
|
|
|
241
268
|
def clear_#{list_m}
|
|
242
|
-
Og.db.exec("DELETE FROM #{
|
|
269
|
+
Og.db.exec("DELETE FROM #{Backend.join_table(self, klass)} WHERE key2=\#\@oid")
|
|
243
270
|
end
|
|
244
271
|
}
|
|
245
272
|
end
|
|
246
273
|
alias :has_and_belongs_to_many :many_to_many
|
|
247
274
|
|
|
275
|
+
# Implements a 'refers_to' relation.
|
|
276
|
+
# This is a one-way version of the 'has_one'/'belongs_to'
|
|
277
|
+
# relations. The target object cannot link back to the source
|
|
278
|
+
# object.
|
|
279
|
+
# This is in fact EXACTLY the same as belongs_to with a
|
|
280
|
+
# different name (!!!!)
|
|
281
|
+
#
|
|
282
|
+
# Automatically enchants the calling class with helper methods.
|
|
283
|
+
#
|
|
284
|
+
#
|
|
285
|
+
# Example:
|
|
286
|
+
#
|
|
287
|
+
# class MyObject
|
|
288
|
+
# refers_to article, Article
|
|
289
|
+
# end
|
|
290
|
+
#
|
|
291
|
+
# creates the code:
|
|
292
|
+
#
|
|
293
|
+
# prop_accessor Fixnum, :article_oid
|
|
294
|
+
# def article; ... end
|
|
295
|
+
# def article=(obj_or_oid); ... end
|
|
296
|
+
|
|
297
|
+
def refers_to(name, klass, options = {})
|
|
298
|
+
prop_eval = "prop_accessor Fixnum, :#{name}_oid"
|
|
299
|
+
prop_eval << ", :sql => '#{options[:sql]}'" if options[:sql]
|
|
300
|
+
prop_eval << ", :extra_sql => '#{options[:extra_sql]}'" if options[:extra_sql]
|
|
301
|
+
|
|
302
|
+
meta :refers_to, klass
|
|
303
|
+
klass.meta :has, [self, "#{name}_oid"]
|
|
304
|
+
|
|
305
|
+
module_eval %{
|
|
306
|
+
#{prop_eval}
|
|
307
|
+
|
|
308
|
+
def #{name}
|
|
309
|
+
Og.db.load_by_oid(@#{name}_oid, #{klass})
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def #{name}=(obj_or_oid)
|
|
313
|
+
@#{name}_oid = obj_or_oid.to_i
|
|
314
|
+
end
|
|
315
|
+
}
|
|
316
|
+
end
|
|
317
|
+
|
|
248
318
|
end
|
|
249
319
|
|
|
250
|
-
end
|
|
320
|
+
end
|
|
251
321
|
|
|
252
322
|
# Include the meta-language extensions into Module. If the flag is
|
|
253
323
|
# false the developer is responsible for including the MetaLanguage
|
|
254
324
|
# module where needed.
|
|
255
|
-
#
|
|
325
|
+
#
|
|
326
|
+
# By default this is FALSE, to avoid polution of the Module object.
|
|
327
|
+
# However if you include a prop_accessor or a managed Mixin in your
|
|
328
|
+
# object MetaLanguage gets automatically extended in the class.
|
|
329
|
+
|
|
256
330
|
if Og.include_meta_language
|
|
257
331
|
class Module # :nodoc: all
|
|
258
332
|
include Og::MetaLanguage
|
|
259
333
|
end
|
|
260
334
|
end
|
|
261
|
-
|