lore 0.4.8 → 0.9.2
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/Manifest.txt +16 -7
- data/README.rdoc +91 -0
- data/benchmark/benchmark.sql +11 -0
- data/benchmark/results.txt +28 -0
- data/benchmark/select.rb +352 -0
- data/lib/lore.rb +22 -8
- data/lib/lore/adapters/context.rb +64 -0
- data/lib/lore/adapters/postgres-pr.rb +6 -0
- data/lib/lore/adapters/postgres-pr/connection.rb +93 -0
- data/lib/lore/adapters/postgres-pr/result.rb +63 -0
- data/lib/lore/{types.rb → adapters/postgres-pr/types.rb} +36 -0
- data/lib/lore/adapters/postgres.rb +24 -0
- data/lib/lore/adapters/postgres/connection.rb +81 -0
- data/lib/lore/adapters/postgres/result.rb +82 -0
- data/lib/lore/adapters/postgres/types.rb +91 -0
- data/lib/lore/bits.rb +18 -0
- data/lib/lore/cache/abstract_entity_cache.rb +2 -1
- data/lib/lore/cache/cacheable.rb +12 -177
- data/lib/lore/cache/memcache_entity_cache.rb +89 -0
- data/lib/lore/cache/memory_entity_cache.rb +77 -0
- data/lib/lore/cache/mmap_entity_cache.rb +2 -2
- data/lib/lore/cache/mmap_entity_cache_bork.rb +86 -0
- data/lib/lore/clause.rb +107 -35
- data/lib/lore/{exception → exceptions}/ambiguous_attribute.rb +2 -2
- data/lib/lore/{exception → exceptions}/cache_exception.rb +1 -1
- data/lib/lore/exceptions/database_exception.rb +16 -0
- data/lib/lore/{exception/invalid_parameter.rb → exceptions/invalid_field.rb} +7 -4
- data/lib/lore/exceptions/unknown_type.rb +18 -0
- data/lib/lore/exceptions/validation_failure.rb +71 -0
- data/lib/lore/gui/form_generator.rb +109 -60
- data/lib/lore/gui/lore_model_select_field.rb +1 -0
- data/lib/lore/migration.rb +84 -25
- data/lib/lore/model.rb +3 -18
- data/lib/lore/{aspect.rb → model/aspect.rb} +0 -0
- data/lib/lore/model/associations.rb +225 -0
- data/lib/lore/model/attribute_settings.rb +233 -0
- data/lib/lore/model/filters.rb +34 -0
- data/lib/lore/model/mockable.rb +62 -0
- data/lib/lore/{model_factory.rb → model/model_factory.rb} +68 -39
- data/lib/lore/model/model_instance.rb +382 -0
- data/lib/lore/{model_shortcuts.rb → model/model_shortcuts.rb} +7 -0
- data/lib/lore/model/polymorphic.rb +53 -0
- data/lib/lore/model/prepare.rb +97 -0
- data/lib/lore/model/table_accessor.rb +1016 -0
- data/lib/lore/query.rb +71 -0
- data/lib/lore/query_shortcuts.rb +43 -11
- data/lib/lore/strategies/table_delete.rb +115 -0
- data/lib/lore/strategies/table_insert.rb +146 -0
- data/lib/lore/strategies/table_select.rb +299 -0
- data/lib/lore/strategies/table_update.rb +155 -0
- data/lib/lore/validation/parameter_validator.rb +85 -26
- data/lib/lore/validation/type_validator.rb +34 -78
- data/{custom_models.rb → lore-0.9.2.gem} +0 -0
- data/lore.gemspec +26 -17
- data/spec/clause.rb +37 -0
- data/spec/fixtures/blank_models.rb +37 -0
- data/{test/model.rb → spec/fixtures/models.rb} +64 -41
- data/spec/fixtures/polymorphic_models.rb +68 -0
- data/spec/model_associations.rb +86 -0
- data/spec/model_create.rb +47 -0
- data/spec/model_definition.rb +151 -0
- data/spec/model_delete.rb +31 -0
- data/spec/model_inheritance.rb +50 -0
- data/spec/model_polymorphic.rb +85 -0
- data/spec/model_select.rb +101 -0
- data/spec/model_select_eager.rb +42 -0
- data/spec/model_union_select.rb +33 -0
- data/spec/model_update.rb +45 -0
- data/spec/model_validation.rb +20 -0
- data/spec/spec_db.sql +808 -0
- data/spec/spec_env.rb +19 -0
- data/spec/spec_helpers.rb +77 -0
- metadata +93 -82
- data/lib/lore/README.txt +0 -84
- data/lib/lore/behaviours/lockable.rb +0 -55
- data/lib/lore/behaviours/movable.rb +0 -72
- data/lib/lore/behaviours/paginated.rb +0 -31
- data/lib/lore/behaviours/versioned.rb +0 -36
- data/lib/lore/connection.rb +0 -152
- data/lib/lore/exception/invalid_klass_parameters.rb +0 -63
- data/lib/lore/exception/unknown_typecode.rb +0 -19
- data/lib/lore/result.rb +0 -119
- data/lib/lore/symbol.rb +0 -58
- data/lib/lore/table_accessor.rb +0 -1790
- data/lib/lore/table_deleter.rb +0 -116
- data/lib/lore/table_inserter.rb +0 -170
- data/lib/lore/table_instance.rb +0 -389
- data/lib/lore/table_selector.rb +0 -285
- data/lib/lore/table_updater.rb +0 -157
- data/lib/lore/validation.rb +0 -65
- data/lib/lore/validation/message.rb +0 -60
- data/lib/lore/validation/reason.rb +0 -52
- data/lore_test.log +0 -2366
- data/test/README +0 -31
- data/test/custom_models.rb +0 -18
- data/test/env.rb +0 -5
- data/test/prepare.rb +0 -37
- data/test/tc_aspect.rb +0 -58
- data/test/tc_cache.rb +0 -83
- data/test/tc_clause.rb +0 -104
- data/test/tc_deep_inheritance.rb +0 -49
- data/test/tc_factory.rb +0 -57
- data/test/tc_filter.rb +0 -37
- data/test/tc_form.rb +0 -32
- data/test/tc_model.rb +0 -140
- data/test/tc_prepare.rb +0 -44
- data/test/tc_refined_query.rb +0 -88
- data/test/tc_table_accessor.rb +0 -267
- data/test/tc_thread.rb +0 -100
- data/test/test_db.sql +0 -400
- data/test/test_lore.rb +0 -50
data/lib/lore.rb
CHANGED
|
@@ -3,11 +3,12 @@ require('logger')
|
|
|
3
3
|
|
|
4
4
|
module Lore
|
|
5
5
|
|
|
6
|
-
VERSION='0.
|
|
6
|
+
VERSION='0.9.2'
|
|
7
7
|
|
|
8
8
|
@logfile = STDERR
|
|
9
|
-
@
|
|
10
|
-
@
|
|
9
|
+
@query_logfile = STDERR
|
|
10
|
+
@log_queries = true
|
|
11
|
+
@logging_enabled = true
|
|
11
12
|
@cache_entities = false
|
|
12
13
|
@pg_server = 'localhost'
|
|
13
14
|
@pg_port = 5432
|
|
@@ -17,13 +18,25 @@ module Lore
|
|
|
17
18
|
def self.logfile
|
|
18
19
|
@logfile
|
|
19
20
|
end
|
|
21
|
+
def self.query_logfile
|
|
22
|
+
@query_logfile
|
|
23
|
+
end
|
|
20
24
|
def self.logfile=(file)
|
|
21
|
-
@logger
|
|
25
|
+
@logger = Logger.new(file)
|
|
26
|
+
@query_logger = Logger.new(file)
|
|
27
|
+
end
|
|
28
|
+
def self.query_logfile=(file)
|
|
29
|
+
@query_logger = Logger.new(file)
|
|
22
30
|
end
|
|
23
31
|
def self.logger
|
|
24
32
|
@logger
|
|
25
33
|
end
|
|
34
|
+
def self.query_logger
|
|
35
|
+
@query_logger
|
|
36
|
+
end
|
|
37
|
+
|
|
26
38
|
@logger = Logger.new(Lore.logfile)
|
|
39
|
+
@query_logger = Logger.new(Lore.query_logfile)
|
|
27
40
|
|
|
28
41
|
def self.log(&log_block)
|
|
29
42
|
return if Lore.logging_disabled?
|
|
@@ -36,9 +49,11 @@ module Lore
|
|
|
36
49
|
|
|
37
50
|
def self.disable_logging
|
|
38
51
|
@logging_enabled = false
|
|
52
|
+
Lore.logger.level = Logger::ERROR
|
|
39
53
|
end
|
|
40
54
|
def self.enable_logging
|
|
41
55
|
@logging_enabled = true
|
|
56
|
+
Lore.logger.level = Logger::DEBUG
|
|
42
57
|
end
|
|
43
58
|
def self.enable_query_log
|
|
44
59
|
@log_queries = true
|
|
@@ -82,7 +97,7 @@ module Lore
|
|
|
82
97
|
end
|
|
83
98
|
end
|
|
84
99
|
def self.pass_for(dbname)
|
|
85
|
-
@logins[dbname.to_s][1]
|
|
100
|
+
@logins[dbname.to_s][1]
|
|
86
101
|
end
|
|
87
102
|
|
|
88
103
|
def self.disable_cache
|
|
@@ -103,7 +118,6 @@ module Lore
|
|
|
103
118
|
|
|
104
119
|
end
|
|
105
120
|
|
|
121
|
+
require('lore/adapters/postgres')
|
|
106
122
|
require('lore/validation/parameter_validator')
|
|
107
|
-
|
|
108
|
-
require('lore/exception/invalid_klass_parameters')
|
|
109
|
-
require('lore/connection')
|
|
123
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
|
|
2
|
+
require('lore')
|
|
3
|
+
|
|
4
|
+
module Lore
|
|
5
|
+
|
|
6
|
+
class Connection_Error < ::Exception
|
|
7
|
+
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class Context
|
|
11
|
+
|
|
12
|
+
@@context_stack = Array.new
|
|
13
|
+
|
|
14
|
+
def self.get_connection()
|
|
15
|
+
if @@context_stack.empty? then
|
|
16
|
+
raise ::Exception.new('No context given. ')
|
|
17
|
+
end
|
|
18
|
+
return Connection_Pool.get_connection(@@context_stack.last)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.get_context
|
|
22
|
+
@@context_stack.last
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.inspect
|
|
26
|
+
@@context_stack.inspect
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.enter(context_name)
|
|
30
|
+
Lore.logger.debug { "Entering context #{context_name}" }
|
|
31
|
+
@@context_stack.push(context_name.to_sym)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.leave()
|
|
35
|
+
Lore.logger.debug { "Leaving context #{context_name}" }
|
|
36
|
+
context_name = @@context_stack.pop
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class Connection_Pool
|
|
42
|
+
|
|
43
|
+
@@pool = Hash.new
|
|
44
|
+
|
|
45
|
+
def self.get_connection(db_name)
|
|
46
|
+
|
|
47
|
+
db_name = db_name.to_sym
|
|
48
|
+
|
|
49
|
+
# If requested connection is not in pool yet:
|
|
50
|
+
if !@@pool.has_key? db_name then
|
|
51
|
+
# Try to establish connection
|
|
52
|
+
connection = Lore::Connection.establish(db_name)
|
|
53
|
+
connection.exec(Lore.on_connect_commands)
|
|
54
|
+
@@pool[db_name] = connection
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Return requested connection
|
|
58
|
+
return @@pool[db_name]
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end # module Lore
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
|
|
2
|
+
$:.push('/opt/local/lib/ruby/1.8/postgres')
|
|
3
|
+
|
|
4
|
+
require('postgres-pr/connection')
|
|
5
|
+
require('lore')
|
|
6
|
+
require('lore/exceptions/database_exception')
|
|
7
|
+
require('lore/adapters/context')
|
|
8
|
+
require('lore/adapters/postgres-pr/result')
|
|
9
|
+
require('lore/adapters/postgres-pr/types')
|
|
10
|
+
|
|
11
|
+
module PostgresPR
|
|
12
|
+
class Connection
|
|
13
|
+
alias exec query
|
|
14
|
+
alias exec_async query
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
module Lore
|
|
19
|
+
|
|
20
|
+
class Connection
|
|
21
|
+
|
|
22
|
+
@@query_count = 0
|
|
23
|
+
@@result_row_count = 0
|
|
24
|
+
|
|
25
|
+
def initialize
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.reset_query_count
|
|
29
|
+
@@query_count = 0
|
|
30
|
+
end
|
|
31
|
+
def self.reset_result_row_count
|
|
32
|
+
@@result_row_count = 0
|
|
33
|
+
end
|
|
34
|
+
def self.query_count
|
|
35
|
+
@@query_count
|
|
36
|
+
end
|
|
37
|
+
def self.result_row_count
|
|
38
|
+
@@result_row_count
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.perform_cacheable(query)
|
|
42
|
+
if Lore::Cache::Cached_Entities.include?(query) then
|
|
43
|
+
result = Lore::Cache::Cached_Entities[query]
|
|
44
|
+
else
|
|
45
|
+
result = perform(query)
|
|
46
|
+
Lore::Cache::Cached_Entities[query] = result
|
|
47
|
+
end
|
|
48
|
+
return result
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.perform(query)
|
|
52
|
+
begin
|
|
53
|
+
@@query_count += 1
|
|
54
|
+
# result = Context.get_connection.exec(query)
|
|
55
|
+
result = Context.get_connection.query(query)
|
|
56
|
+
@@result_row_count += result.rows.length
|
|
57
|
+
|
|
58
|
+
if Lore.log_queries? then
|
|
59
|
+
query.split("\n").each { |line|
|
|
60
|
+
Lore.query_logger.debug { " sql|#{Context.get_context}| #{line}" }
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
rescue ::Exception => pge
|
|
64
|
+
Lore.logger.error { pge.message }
|
|
65
|
+
Lore.logger.error { 'Context: ' << Context.inspect }
|
|
66
|
+
Lore.logger.error { 'Query: ' << "\n" << query }
|
|
67
|
+
raise pge
|
|
68
|
+
raise Lore::Exceptions::Database_Exception.new(pge.message << "\n" << query.to_s)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
return Result.new(query, result)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def self.establish(db_name)
|
|
75
|
+
Lore.logger.info { "Establishing connection to #{db_name}" }
|
|
76
|
+
Lore.logger.info { "User: #{Lore.user_for(db_name.to_sym).inspect}"}
|
|
77
|
+
Lore.logger.info { "Pass: #{Lore.pass_for(db_name.to_sym).inspect}"}
|
|
78
|
+
Lore.logger.info { "Server: #{Lore.pg_server}" }
|
|
79
|
+
begin
|
|
80
|
+
PostgresPR::Connection.new(db_name.to_s,
|
|
81
|
+
Lore.user_for(db_name.to_sym),
|
|
82
|
+
Lore.pass_for(db_name.to_sym),
|
|
83
|
+
# including port, example:
|
|
84
|
+
# 'unix:/var/run/postgresql/.s.PGSQL.5432'
|
|
85
|
+
Lore.pg_server)
|
|
86
|
+
rescue ::Exception => e
|
|
87
|
+
raise Lore::Exceptions::Database_Exception.new(e.message)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end # class Connection
|
|
92
|
+
|
|
93
|
+
end # module Lore
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
|
|
2
|
+
require('postgres-pr/connection')
|
|
3
|
+
|
|
4
|
+
module Lore
|
|
5
|
+
|
|
6
|
+
class Result
|
|
7
|
+
|
|
8
|
+
attr_reader :query_hashval, :field_names, :field_types
|
|
9
|
+
|
|
10
|
+
# expects PostgresPR::Result
|
|
11
|
+
def initialize(query, result)
|
|
12
|
+
@result = result
|
|
13
|
+
@field_types = {}
|
|
14
|
+
@result.fields.each { |f|
|
|
15
|
+
@field_types[f.name] = f.type_oid
|
|
16
|
+
}
|
|
17
|
+
@num_fields = @result.fields.length
|
|
18
|
+
@num_tuples = @result.rows.length
|
|
19
|
+
@field_names = @result.fields.map { |f| f.name }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get_field_value(row_index, field_name)
|
|
23
|
+
# TODO: Optimize this!
|
|
24
|
+
field_index = 0
|
|
25
|
+
@result.fields.each { |f|
|
|
26
|
+
break if f.name == field_name
|
|
27
|
+
field_index += 1
|
|
28
|
+
}
|
|
29
|
+
return @result.rows[row_index][field_index]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def get_field_types()
|
|
33
|
+
return @field_types
|
|
34
|
+
end
|
|
35
|
+
alias field_types get_field_types
|
|
36
|
+
alias get_field_names field_names
|
|
37
|
+
|
|
38
|
+
def get_field_num()
|
|
39
|
+
@num_fields
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def get_tuple_num()
|
|
43
|
+
@num_tuples
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def get_row(row_num=0)
|
|
47
|
+
@result.rows[row_num]
|
|
48
|
+
end
|
|
49
|
+
def get_row_with_field_names(row_num=0)
|
|
50
|
+
return { :values => @result.rows, :fields => @result.fields }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def get_rows()
|
|
54
|
+
return @result.rows
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def fieldname(index)
|
|
58
|
+
return @fields_names[index]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end # class Result
|
|
62
|
+
|
|
63
|
+
end # module Lore
|
|
@@ -7,6 +7,7 @@ module Lore
|
|
|
7
7
|
PG_CHAR = 18
|
|
8
8
|
PG_INT = 23
|
|
9
9
|
PG_TEXT = 25
|
|
10
|
+
PG_FLOAT = 701
|
|
10
11
|
PG_CHARACTER = 1042
|
|
11
12
|
PG_VARCHAR = 1043
|
|
12
13
|
PG_TIME = 1083
|
|
@@ -23,6 +24,7 @@ module Lore
|
|
|
23
24
|
PG_CHAR => 'char',
|
|
24
25
|
PG_INT => 'integer',
|
|
25
26
|
PG_TEXT => 'text',
|
|
27
|
+
PG_FLOAT => 'float',
|
|
26
28
|
PG_CHARACTER => 'character',
|
|
27
29
|
PG_VARCHAR => 'character varying(1000)',
|
|
28
30
|
PG_TIME => 'time',
|
|
@@ -52,4 +54,38 @@ module Lore
|
|
|
52
54
|
|
|
53
55
|
end
|
|
54
56
|
|
|
57
|
+
class Type_Filters
|
|
58
|
+
|
|
59
|
+
@@input_filters = {
|
|
60
|
+
PG_VCHAR_LIST => lambda { |v| "{#{v.join(',')}}" },
|
|
61
|
+
PG_BOOL => lambda { |v| if (v && v != 'f' || v == 't') then 'f' elsif (v.instance_of?(FalseClass) || v == 'f') then 'f' else nil end },
|
|
62
|
+
PG_DATE => lambda { |v| v.to_s },
|
|
63
|
+
PG_TIME => lambda { |v| v.to_s },
|
|
64
|
+
PG_TIMESTAMP_TIMEZONE => lambda { |v| v.to_s },
|
|
65
|
+
PG_TIMESTAMP => lambda { |v| v.to_s },
|
|
66
|
+
}
|
|
67
|
+
@@output_filters = {
|
|
68
|
+
PG_VCHAR_LIST => lambda { |v| v[1..-2].split(',') },
|
|
69
|
+
PG_INT => lambda { |v| if v then v.to_i else nil end },
|
|
70
|
+
PG_SMALLINT => lambda { |v| if v then v.to_i else nil end },
|
|
71
|
+
PG_FLOAT => lambda { |v| if v && v.length > 0 then v.to_f else nil end },
|
|
72
|
+
PG_DECIMAL => lambda { |v| if v && v.length > 0 then v.to_f else nil end },
|
|
73
|
+
PG_BOOL => lambda { |v| if v == 't' then true elsif v == 'f' then false else nil end }
|
|
74
|
+
# SLOW!
|
|
75
|
+
# PG_DATE => lambda { |v| Date.parse(v) if v },
|
|
76
|
+
# PG_TIME => lambda { |v| Time.parse(v) if v },
|
|
77
|
+
# PG_TIMESTAMP_TIMEZONE => lambda { |v| DateTime.parse(v) if v },
|
|
78
|
+
# PG_TIMESTAMP => lambda { |v| DateTime.parse(v) if v }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
def self.in
|
|
82
|
+
@@input_filters
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def self.out
|
|
86
|
+
@@output_filters
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
|
|
55
91
|
end # module
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
require('rubygems')
|
|
3
|
+
begin
|
|
4
|
+
require('postgres')
|
|
5
|
+
require('lore/adapters/postgres/connection')
|
|
6
|
+
require('lore/adapters/postgres/result')
|
|
7
|
+
require('lore/adapters/postgres/types')
|
|
8
|
+
rescue LoadError
|
|
9
|
+
begin
|
|
10
|
+
Lore.pg_server = 'unix:/var/run/postgresql/.s.PGSQL.5432'
|
|
11
|
+
Lore.logger.info { "Defaulted PG server to #{Lore.pg_server}" }
|
|
12
|
+
Lore.logger.info { "Use Lore.pg_server = 'server uri' to set a different one" }
|
|
13
|
+
# Bridges PostgresPR::Connection to PGConn
|
|
14
|
+
# require 'postgres-pr/postgres-compat'
|
|
15
|
+
require('postgres-pr/connection')
|
|
16
|
+
require('lore/adapters/postgres-pr/connection')
|
|
17
|
+
require('lore/adapters/postgres-pr/result')
|
|
18
|
+
require('lore/adapters/postgres-pr/types')
|
|
19
|
+
rescue LoadError
|
|
20
|
+
Lore.logger.error { "No binding for postgres found" }
|
|
21
|
+
Lore.logger.error { "Please install 'postgres' or 'postgres-pr'" }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
|
|
2
|
+
$:.push('/opt/local/lib/ruby/1.8/postgres')
|
|
3
|
+
|
|
4
|
+
require('postgres')
|
|
5
|
+
require('lore')
|
|
6
|
+
require('lore/exceptions/database_exception')
|
|
7
|
+
require('lore/adapters/context')
|
|
8
|
+
require('lore/adapters/postgres/result')
|
|
9
|
+
|
|
10
|
+
module Lore
|
|
11
|
+
|
|
12
|
+
class Connection
|
|
13
|
+
|
|
14
|
+
@@query_count = 0
|
|
15
|
+
@@result_row_count = 0
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.reset_query_count
|
|
21
|
+
@@query_count = 0
|
|
22
|
+
end
|
|
23
|
+
def self.reset_result_row_count
|
|
24
|
+
@@result_row_count = 0
|
|
25
|
+
end
|
|
26
|
+
def self.query_count
|
|
27
|
+
@@query_count
|
|
28
|
+
end
|
|
29
|
+
def self.result_row_count
|
|
30
|
+
@@result_row_count
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.perform_cacheable(query)
|
|
34
|
+
if Lore::Cache::Cached_Entities.include?(query) then
|
|
35
|
+
result = Lore::Cache::Cached_Entities[query]
|
|
36
|
+
else
|
|
37
|
+
result = perform(query)
|
|
38
|
+
Lore::Cache::Cached_Entities[query] = result
|
|
39
|
+
end
|
|
40
|
+
return result
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.perform(query)
|
|
44
|
+
begin
|
|
45
|
+
@@query_count += 1
|
|
46
|
+
# result = Context.get_connection.exec(query)
|
|
47
|
+
result = Context.get_connection.async_exec(query)
|
|
48
|
+
@@result_row_count += result.num_tuples
|
|
49
|
+
|
|
50
|
+
if Lore.log_queries? then
|
|
51
|
+
query.split("\n").each { |line|
|
|
52
|
+
Lore.query_logger.debug { " sql|#{Context.get_context}| #{line}" }
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
rescue ::Exception => pge
|
|
56
|
+
pge.message << "\n" << query.inspect
|
|
57
|
+
Lore.logger.error { pge.message }
|
|
58
|
+
Lore.logger.error { 'Context: ' << Context.inspect }
|
|
59
|
+
Lore.logger.error { 'Query: ' << "\n" << query }
|
|
60
|
+
raise Lore::Exceptions::Database_Exception.new(pge.message << "\n" << query.to_s)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
return Result.new(query, result)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.establish(db_name)
|
|
67
|
+
begin
|
|
68
|
+
PGconn.connect(Lore.pg_server,
|
|
69
|
+
Lore.pg_port,
|
|
70
|
+
'', '',
|
|
71
|
+
db_name.to_s,
|
|
72
|
+
Lore.user_for(db_name.to_sym),
|
|
73
|
+
Lore.pass_for(db_name.to_sym))
|
|
74
|
+
rescue ::Exception => e
|
|
75
|
+
raise Lore::Exceptions::Database_Exception.new(e.message)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end # class Connection
|
|
80
|
+
|
|
81
|
+
end # module Lore
|