lore 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/README +74 -0
- data/aspect.rb +80 -0
- data/behaviours/lockable.rb +41 -0
- data/behaviours/movable.rb +54 -0
- data/behaviours/versioned.rb +24 -0
- data/benchmark.rb +193 -0
- data/bits.rb +52 -0
- data/cache/abstract_entity_cache.rb +82 -0
- data/cache/bits.rb +22 -0
- data/cache/cacheable.rb +202 -0
- data/cache/cached_entities.rb +116 -0
- data/cache/file_index.rb +35 -0
- data/cache/mmap_entity_cache.rb +67 -0
- data/clause.rb +528 -0
- data/connection.rb +155 -0
- data/custom_functions.sql +14 -0
- data/exception/ambiguous_attribute.rb +14 -0
- data/exception/cache_exception.rb +30 -0
- data/exception/invalid_klass_parameters.rb +63 -0
- data/exception/invalid_parameter.rb +42 -0
- data/exception/unknown_typecode.rb +19 -0
- data/file_index.sql +56 -0
- data/gui/erb_template.rb +79 -0
- data/gui/erb_template_helpers.rhtml +19 -0
- data/gui/form.rb +314 -0
- data/gui/form_element.rb +676 -0
- data/gui/form_generator.rb +151 -0
- data/gui/templates/button.rhtml +2 -0
- data/gui/templates/checkbox.rhtml +3 -0
- data/gui/templates/checkbox_row.rhtml +1 -0
- data/gui/templates/file.rhtml +2 -0
- data/gui/templates/file_readonly.rhtml +3 -0
- data/gui/templates/form_element.rhtml +5 -0
- data/gui/templates/form_element_horizontal.rhtml +3 -0
- data/gui/templates/form_element_listed.rhtml +8 -0
- data/gui/templates/form_table.rhtml +3 -0
- data/gui/templates/form_table_blank.rhtml +3 -0
- data/gui/templates/form_table_horizontal.rhtml +8 -0
- data/gui/templates/password.rhtml +2 -0
- data/gui/templates/password_readonly.rhtml +3 -0
- data/gui/templates/radio.rhtml +1 -0
- data/gui/templates/radio_row.rhtml +1 -0
- data/gui/templates/select.rhtml +23 -0
- data/gui/templates/text.rhtml +2 -0
- data/gui/templates/text_readonly.rhtml +3 -0
- data/gui/templates/textarea.rhtml +3 -0
- data/gui/templates/textarea_readonly.rhtml +4 -0
- data/lore.gemspec +40 -0
- data/lore.rb +94 -0
- data/migration.rb +48 -0
- data/model.rb +139 -0
- data/model_factory.rb +202 -0
- data/model_shortcuts.rb +16 -0
- data/query_shortcuts.rb +367 -0
- data/reserved_methods.txt +3 -0
- data/result.rb +100 -0
- data/symbol.rb +58 -0
- data/table_accessor.rb +1926 -0
- data/table_deleter.rb +115 -0
- data/table_inserter.rb +168 -0
- data/table_instance.rb +384 -0
- data/table_selector.rb +314 -0
- data/table_updater.rb +155 -0
- data/test/README +31 -0
- data/test/env.rb +5 -0
- data/test/lore_test.log +8218 -0
- data/test/model.rb +142 -0
- data/test/prepare.rb +37 -0
- data/test/tc_aspect.rb +58 -0
- data/test/tc_cache.rb +80 -0
- data/test/tc_clause.rb +104 -0
- data/test/tc_deep_inheritance.rb +49 -0
- data/test/tc_factory.rb +57 -0
- data/test/tc_filter.rb +37 -0
- data/test/tc_form.rb +32 -0
- data/test/tc_model.rb +86 -0
- data/test/tc_prepare.rb +45 -0
- data/test/tc_refined_query.rb +88 -0
- data/test/tc_table_accessor.rb +265 -0
- data/test/test.log +181 -0
- data/test/test_db.sql +400 -0
- data/test/ts_lore.rb +49 -0
- data/types.rb +55 -0
- data/validation/message.rb +60 -0
- data/validation/parameter_validator.rb +104 -0
- data/validation/reason.rb +54 -0
- data/validation/type_validator.rb +91 -0
- data/validation.rb +65 -0
- metadata +170 -0
@@ -0,0 +1,151 @@
|
|
1
|
+
|
2
|
+
require('lore/types')
|
3
|
+
require('lore/gui/form')
|
4
|
+
|
5
|
+
module Lore
|
6
|
+
module GUI
|
7
|
+
|
8
|
+
# Usage:
|
9
|
+
#
|
10
|
+
# generator = Form_Generator.new(Table_Accessor, Lang, :readonly | :mutable)
|
11
|
+
# form = generator.generate
|
12
|
+
#
|
13
|
+
# See documentation of Cuba::GUI::Form for usage of form instances.
|
14
|
+
#
|
15
|
+
class Form_Generator
|
16
|
+
|
17
|
+
def initialize(klass=nil, labels={}, mode=:mutable, custom_elements={}) # {{{
|
18
|
+
|
19
|
+
@logger = Lore.logger
|
20
|
+
@form = Form.new()
|
21
|
+
@labels = labels
|
22
|
+
@klass = klass
|
23
|
+
@custom_elements = custom_elements
|
24
|
+
|
25
|
+
Textarea.reset_counter
|
26
|
+
|
27
|
+
@logger.debug('CUSTOM ELEMENTS: ' << @custom_elements.inspect)
|
28
|
+
|
29
|
+
if @klass.nil? then return end
|
30
|
+
@logger.debug('GET_ATTRIBUTES: ' << @klass.inspect)
|
31
|
+
@logger.debug('GET_ATTRIBUTES: ' << @klass.get_attributes.inspect)
|
32
|
+
@klass.get_attributes.each_pair { |table, attributes|
|
33
|
+
|
34
|
+
# handle attributes passed via attrib_setup:
|
35
|
+
|
36
|
+
attributes.each { |attrib|
|
37
|
+
|
38
|
+
label_tag = table.gsub('.','--') << '--' << attrib
|
39
|
+
if(@labels[label_tag].to_s != '' && @labels[label_tag] != label_tag) then
|
40
|
+
label = @labels[label_tag]
|
41
|
+
else
|
42
|
+
label = attrib.gsub('_',' ').capitalize
|
43
|
+
end
|
44
|
+
|
45
|
+
# @custom_elements is a hash mapping attribute names to
|
46
|
+
# Custom_Element instances.
|
47
|
+
if ((@custom_elements[table]) and
|
48
|
+
(@custom_elements[table][attrib])) then
|
49
|
+
|
50
|
+
form_element = @custom_elements[table][attrib].new(table, attrib, label)
|
51
|
+
form_element.mode = mode
|
52
|
+
@form.add(form_element)
|
53
|
+
|
54
|
+
elsif (@klass.get_primary_keys[table].nil? or
|
55
|
+
!@klass.get_primary_keys[table].include? attrib) and
|
56
|
+
(@klass.get_implicit_attributes[table].nil? or
|
57
|
+
!@klass.get_implicit_attributes[table].include? attrib) and
|
58
|
+
(@klass.get_has_a_klasses.nil? or
|
59
|
+
@klass.get_has_a_klasses[table+'.'+attrib].nil?) and
|
60
|
+
(@klass.get_hidden_attributes[table].nil? or
|
61
|
+
!@klass.get_hidden_attributes[table].include? attrib)
|
62
|
+
then
|
63
|
+
|
64
|
+
case @klass.get_attribute_types[table][attrib]
|
65
|
+
|
66
|
+
when Lore::PG_BOOL
|
67
|
+
form_element = Radio.new(table, attrib, label, ['t','f'])
|
68
|
+
|
69
|
+
when Lore::PG_SMALLINT || Lore::PG_INT
|
70
|
+
form_element = Text.new(table, attrib, label, nil)
|
71
|
+
|
72
|
+
when Lore::PG_VARCHAR
|
73
|
+
form_element = Text.new(table, attrib, label, nil, nil)
|
74
|
+
if (!@klass.get_maxlength.nil? &&
|
75
|
+
!@klass.get_maxlength[table].nil? &&
|
76
|
+
!@klass.get_maxlength[table][attrib.intern].nil?) then
|
77
|
+
form_element.set_length(@klass.get_maxlength[table][attrib.intern])
|
78
|
+
end
|
79
|
+
|
80
|
+
when Lore::PG_TEXT
|
81
|
+
form_element = Textarea.new(table, attrib, label, nil, nil)
|
82
|
+
if (!@klass.get_maxlength.nil? &&
|
83
|
+
!@klass.get_maxlength[table].nil? &&
|
84
|
+
!@klass.get_maxlength[table][attrib.intern].nil?) then
|
85
|
+
form_element.set_length(@klass.get_maxlength[table][attrib.intern])
|
86
|
+
end
|
87
|
+
|
88
|
+
when Lore::PG_TIMESTAMP_TIMEZONE
|
89
|
+
form_element = Date.new(table, attrib, label, nil)
|
90
|
+
|
91
|
+
when Lore::PG_DATE
|
92
|
+
form_element = Date.new(table, attrib, label, nil)
|
93
|
+
|
94
|
+
else
|
95
|
+
form_element = Text.new(table, attrib, label, nil)
|
96
|
+
end
|
97
|
+
|
98
|
+
form_element.set_mode(mode)
|
99
|
+
@form.add(form_element)
|
100
|
+
|
101
|
+
elsif (!@klass.get_has_a_klasses.nil? and
|
102
|
+
!@klass.get_has_a_klasses[table+'.'+attrib].nil?)
|
103
|
+
then
|
104
|
+
foreign_klass = @klass.get_has_a_klasses[table+'.'+attrib]
|
105
|
+
foreign_table = foreign_klass.table_name
|
106
|
+
|
107
|
+
form_element = Klass_Select.new(foreign_klass, table, attrib, label)
|
108
|
+
form_element.set_mode(mode)
|
109
|
+
@form.add(form_element)
|
110
|
+
|
111
|
+
elsif (!@klass.get_aggregate_klasses.nil? and
|
112
|
+
!@klass.get_aggregate_klasses[table+'.'+attrib].nil?)
|
113
|
+
then
|
114
|
+
foreign_klass = @klass.get_aggregate_klasses[table+'.'+attrib]
|
115
|
+
foreign_table = foreign_klass.table_name
|
116
|
+
|
117
|
+
form_element = Klass_Select.new(foreign_klass, table, attrib, label)
|
118
|
+
form_element.set_mode(mode)
|
119
|
+
@form.add(form_element)
|
120
|
+
|
121
|
+
# Attribute is explixit (expected/required) but not
|
122
|
+
# catched before -> Add attribute as hidden field:
|
123
|
+
elsif (!@klass.get_explicit_attributes[table].nil? and
|
124
|
+
@klass.get_explicit_attributes[table].include? attrib)
|
125
|
+
then
|
126
|
+
form_element = Hidden.new(table, attrib)
|
127
|
+
@form.add(form_element)
|
128
|
+
|
129
|
+
elsif (!@klass.get_implicit_attributes[table].nil? and
|
130
|
+
@klass.get_implicit_attributes[table].include? attrib)
|
131
|
+
then
|
132
|
+
@logger.debug(attrib+' is implicit')
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
}
|
137
|
+
}
|
138
|
+
end # }}}
|
139
|
+
|
140
|
+
# Returns instance of Cuba::GUI::Form configured
|
141
|
+
# for klass passed in constructor:
|
142
|
+
def generate() # {{{
|
143
|
+
return @form
|
144
|
+
end # }}}
|
145
|
+
|
146
|
+
end # class
|
147
|
+
|
148
|
+
|
149
|
+
end # module
|
150
|
+
end # module
|
151
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
<div class="lore_checkbox_row"><%= checkboxes %></div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<nobr><font style="width: 120px; "><input type="radio" <%= tag_attributes(attributes) %> /> <%= attributes[:label] %> </font></nobr>
|
@@ -0,0 +1 @@
|
|
1
|
+
<div class="lore_radio_row"><%= radios %></div>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<div class="lore_select_wrap">
|
2
|
+
<select <%= tag_attributes(attributes) %> >
|
3
|
+
<%=
|
4
|
+
option_index = 0
|
5
|
+
options = "\n"
|
6
|
+
|
7
|
+
range.each { |attrib|
|
8
|
+
attrib = attrib.to_s
|
9
|
+
|
10
|
+
if value.to_s == attrib.to_s then
|
11
|
+
selected = 'selected'
|
12
|
+
else selected = '' end
|
13
|
+
|
14
|
+
options += '<option value="'+attrib.to_s+'" '+selected+' >'
|
15
|
+
options += labels[option_index].to_s
|
16
|
+
options += '</options>'
|
17
|
+
|
18
|
+
option_index += 1
|
19
|
+
}
|
20
|
+
options
|
21
|
+
%>
|
22
|
+
</select>
|
23
|
+
</div>
|
data/lore.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
spec = Gem::Specification.new { |s|
|
5
|
+
|
6
|
+
s.name = 'lore'
|
7
|
+
s.rubyforge_project = 'lore'
|
8
|
+
s.summary = 'A flexible ORM based on PostgreSQL'
|
9
|
+
s.description = <<-EOF
|
10
|
+
Lore is an object-relational mapping (ORM) implementation
|
11
|
+
providing many features like prepared statements,
|
12
|
+
(multiple) inheritance, a comfortable query syntax,
|
13
|
+
highly customizable automated form generation,
|
14
|
+
and result caching using memory mapping (MMap).
|
15
|
+
Lore is currently using PostgreSQL as database backend.
|
16
|
+
EOF
|
17
|
+
s.version = '0.4.2'
|
18
|
+
s.author = 'Tobias Fuchs'
|
19
|
+
s.email = 'fuchs@atomnode.net'
|
20
|
+
s.date = Time.now
|
21
|
+
s.files = '*.rb'
|
22
|
+
s.add_dependency('mmap', '>= 0.1')
|
23
|
+
s.add_dependency('postgres', '>= 0.1')
|
24
|
+
s.files = FileList['*',
|
25
|
+
'behaviours/*',
|
26
|
+
'test/*',
|
27
|
+
'cache/*',
|
28
|
+
'validation/*',
|
29
|
+
'gui/*',
|
30
|
+
'gui/templates/*',
|
31
|
+
'exception/*'].to_a
|
32
|
+
|
33
|
+
s.has_rdoc = true
|
34
|
+
s.rdoc_options << '--title' << 'Lore ORM' <<
|
35
|
+
'--main' << 'README' <<
|
36
|
+
'--line-numbers'
|
37
|
+
|
38
|
+
s.homepage = 'http://lore.rubyforge.org'
|
39
|
+
|
40
|
+
}
|
data/lore.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
|
2
|
+
require('logger')
|
3
|
+
|
4
|
+
module Lore
|
5
|
+
|
6
|
+
@logfile = '/var/log/lore/query.log'
|
7
|
+
def self.logfile
|
8
|
+
@logfile
|
9
|
+
end
|
10
|
+
def self.logfile=(file)
|
11
|
+
@logger = Logger.new(file)
|
12
|
+
end
|
13
|
+
def self.logger
|
14
|
+
@logger
|
15
|
+
end
|
16
|
+
@logger = Logger.new(Lore.logfile)
|
17
|
+
|
18
|
+
def self.log(&log_block)
|
19
|
+
return if Lore.logging_disabled?
|
20
|
+
Lore.logger.debug(&log_block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.log_queries?
|
24
|
+
true
|
25
|
+
end
|
26
|
+
def self.logging_disabled?
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
@cache_entities = false
|
31
|
+
|
32
|
+
@logins = {
|
33
|
+
}
|
34
|
+
|
35
|
+
def self.set_login_data(login_hash)
|
36
|
+
@logins = login_hash
|
37
|
+
end
|
38
|
+
def self.add_login_data(login_hash)
|
39
|
+
@logins.update(login_hash)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.path
|
43
|
+
File.expand_path(File.dirname(__FILE__)) + '/'
|
44
|
+
end
|
45
|
+
|
46
|
+
@pg_server = 'localhost'
|
47
|
+
@pg_port = 5432
|
48
|
+
|
49
|
+
def self.pg_server
|
50
|
+
@pg_server
|
51
|
+
end
|
52
|
+
def self.pg_port
|
53
|
+
@pg_port
|
54
|
+
end
|
55
|
+
def self.pg_server=(s)
|
56
|
+
@pg_server = s
|
57
|
+
end
|
58
|
+
def self.pg_port=(p)
|
59
|
+
@pg_port = p
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.user_for(dbname)
|
63
|
+
begin
|
64
|
+
@logins[dbname.to_s][0].to_s
|
65
|
+
rescue ::Exception => excep
|
66
|
+
raise ::Exception.new('Unable to resolve user for database ' << dbname.inspect)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
def self.pass_for(dbname)
|
70
|
+
@logins[dbname.to_s][1].to_s
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.disable_cache
|
74
|
+
@cache_entities = false
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.enable_cache
|
78
|
+
@cache_entities = true
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.cache_enabled?
|
82
|
+
@cache_entities
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.on_connect_commands()
|
86
|
+
"set client_encoding to Unicode; set datestyle to 'European'"
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
require('lore/validation/parameter_validator')
|
92
|
+
require('lore/exception/invalid_parameter')
|
93
|
+
require('lore/exception/invalid_klass_parameters')
|
94
|
+
require('lore/connection')
|
data/migration.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
module Lore
|
3
|
+
|
4
|
+
|
5
|
+
# Usage:
|
6
|
+
#
|
7
|
+
# Using auto-bootstrap of models:
|
8
|
+
#
|
9
|
+
# class My_Model < Lore::Model
|
10
|
+
# extend Lore::Migration
|
11
|
+
#
|
12
|
+
# table :my_model, :public
|
13
|
+
# primary_key :key_a, :key_a_seq
|
14
|
+
# primary_key :key_b
|
15
|
+
#
|
16
|
+
# has_attributes {
|
17
|
+
# :foo, Lore::Type.integer, { :unique => true, :default => 1 }
|
18
|
+
# :bar, Lore::Type.integer, { :not_null => true, :check => 'bar < 1000' }
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
# def self.up
|
22
|
+
# bootstrap()
|
23
|
+
# My_Model.create(:foo => 23, :bar => 123)
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
module Migration
|
29
|
+
|
30
|
+
def has_attributes(attrib_hash)
|
31
|
+
@model_schema = attrib_hash
|
32
|
+
end
|
33
|
+
|
34
|
+
def update_schema
|
35
|
+
@factory = Model_Factory.new(self.class.to_s)
|
36
|
+
@model_schema.each_pair { |attrib_name, attrib_props|
|
37
|
+
@factory.add_attribute(attrib_name.to_s, attrib_props)
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
def bootstrap
|
42
|
+
@factory.build_table
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
data/model.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
|
2
|
+
require('logger')
|
3
|
+
|
4
|
+
require('lore/aspect');
|
5
|
+
require('lore/table_selector');
|
6
|
+
require('lore/table_inserter');
|
7
|
+
require('lore/table_updater');
|
8
|
+
require('lore/table_deleter');
|
9
|
+
require('lore/table_instance');
|
10
|
+
require('lore/query_shortcuts');
|
11
|
+
require('lore/validation');
|
12
|
+
require('lore/migration');
|
13
|
+
require('lore/validation/parameter_validator');
|
14
|
+
require('lore/exception/invalid_parameter');
|
15
|
+
require('lore/exception/invalid_klass_parameters');
|
16
|
+
require('lore/cache/cacheable');
|
17
|
+
require('lore/table_accessor.rb')
|
18
|
+
|
19
|
+
module Lore
|
20
|
+
|
21
|
+
# For API details see Lore::Table_Accessor
|
22
|
+
#
|
23
|
+
#
|
24
|
+
# =How to define models
|
25
|
+
#
|
26
|
+
# Example:
|
27
|
+
#
|
28
|
+
# require 'lore/model'
|
29
|
+
#
|
30
|
+
# class Vehicle < Lore::Model
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# class Car < Vehicle
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# Sets following defaults:
|
37
|
+
#
|
38
|
+
# class Vehicle
|
39
|
+
# table :vehicle, :vehicle_id
|
40
|
+
# primary_key :id # or :vehicle_id if :id is not present
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# class Car < Vehicle
|
44
|
+
# table :car, :public
|
45
|
+
# primary_key :id # or :car_id if :id is not present
|
46
|
+
# is_a Vehicle, :vehicle_id
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# = How to use models
|
50
|
+
#
|
51
|
+
# == Creating entities (INSERTs)
|
52
|
+
#
|
53
|
+
# manuf_1 = Manufacturer.create(:name => 'Audi')
|
54
|
+
# manuf_2 = Manufacturer.create(:name => 'BMW')
|
55
|
+
# car = Car.create(:manufacturer => manuf, :name => 'TT')
|
56
|
+
#
|
57
|
+
# == Changing entities (UPDATEs)
|
58
|
+
#
|
59
|
+
# car['name'] = 'BMW318i'
|
60
|
+
# car.manufacturer = manuf_2 # same as car[:manufacturer_id] = manuf_2.manufacturer_id
|
61
|
+
# car.commit
|
62
|
+
#
|
63
|
+
# == Deleting entities (DELETEs)
|
64
|
+
#
|
65
|
+
# car.delete!
|
66
|
+
# is the same as
|
67
|
+
# Car.delete.where(Car.car_id == car.car_id).perform
|
68
|
+
# is the same as
|
69
|
+
# Lore.perform Car.delete.where(Car.car_id == car.car_id)
|
70
|
+
# is the same as
|
71
|
+
# Car.delete { |c|
|
72
|
+
# c.where(c.car_id = car.car_id)
|
73
|
+
# }
|
74
|
+
#
|
75
|
+
# =How to disable/enable features
|
76
|
+
#
|
77
|
+
# Lore::Model extends
|
78
|
+
# * Lore::Cache::Cacheable
|
79
|
+
# * Lore::Query_Shortcuts
|
80
|
+
# * Lore::Validation
|
81
|
+
# * Lore::Aspect
|
82
|
+
#
|
83
|
+
# Each of them is optional. If you want, for example, a minimalistic
|
84
|
+
# version of Lore::Model with comfortable query interfaces you can define
|
85
|
+
# your own Model class that extends the Lore::Query_Shortcuts module only:
|
86
|
+
#
|
87
|
+
# class Slim_Model < Lore::Table_Accessor
|
88
|
+
# extend Lore::Query_Shortcuts
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# You can use it as base class for other Model classes, too:
|
92
|
+
#
|
93
|
+
# class Cache_Model < Slim_Model
|
94
|
+
# extend Lore::Query_Shortcuts
|
95
|
+
# extend Lore::Cacheable
|
96
|
+
# end
|
97
|
+
#
|
98
|
+
# You also can define this differently for every model by deriving them
|
99
|
+
# from Lore::Table_Accessor and extending every single one of them:
|
100
|
+
#
|
101
|
+
# class User < Lore::Table_Accessor
|
102
|
+
# extend Lore::Query_Shortcuts
|
103
|
+
# extend Lore::Aspect
|
104
|
+
# extend Lore::Validation
|
105
|
+
#
|
106
|
+
# table :user, :public
|
107
|
+
# primary_key :user_id
|
108
|
+
#
|
109
|
+
# end
|
110
|
+
#
|
111
|
+
# =How to use Lore::Model in a Rails app
|
112
|
+
#
|
113
|
+
# By default, Lore::Model doesn't extend Rails interface bridges. You
|
114
|
+
# either can define your own Model base class (see: How to disable/enable
|
115
|
+
# features) and extend it by Lore::Rails::Model
|
116
|
+
#
|
117
|
+
# class My_Model < Lore::Model
|
118
|
+
# extend Lore::Rails::Model
|
119
|
+
# end
|
120
|
+
#
|
121
|
+
# ... or extend Lore::Model directly:
|
122
|
+
#
|
123
|
+
# Lore::Model.extend Lore::Rails_Bridge
|
124
|
+
#
|
125
|
+
# In this case, every Model in your app will include Rails interfaces.
|
126
|
+
#
|
127
|
+
class Model < Table_Accessor
|
128
|
+
extend Lore::Cache::Cacheable
|
129
|
+
extend Lore::Query_Shortcuts
|
130
|
+
extend Lore::Validation
|
131
|
+
extend Lore::Aspect
|
132
|
+
extend Lore::Migration
|
133
|
+
|
134
|
+
def by_id(pkey_id)
|
135
|
+
_by_id(pkey_id).first # Auto-defined in Lore::Table_Accessor.primary_key
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|