momomoto 0.1.15 → 0.1.16
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/lib/momomoto/base.rb +20 -7
- data/lib/momomoto/database.rb +20 -0
- data/lib/momomoto/datatype/array.rb +15 -68
- data/lib/momomoto/datatype/array/base.rb +96 -0
- data/lib/momomoto/datatype/array/integer.rb +27 -0
- data/lib/momomoto/datatype/array/text.rb +16 -0
- data/lib/momomoto/datatype/base.rb +3 -2
- data/lib/momomoto/datatype/bytea.rb +2 -2
- data/lib/momomoto/datatype/date.rb +2 -2
- data/lib/momomoto/datatype/inet.rb +1 -1
- data/lib/momomoto/datatype/interval.rb +5 -5
- data/lib/momomoto/datatype/real.rb +2 -2
- data/lib/momomoto/datatype/smallint.rb +1 -1
- data/lib/momomoto/datatype/text.rb +4 -4
- data/lib/momomoto/datatype/time_without_time_zone.rb +3 -3
- data/lib/momomoto/datatype/timestamp_without_time_zone.rb +2 -2
- data/lib/momomoto/procedure.rb +2 -2
- data/lib/momomoto/table.rb +14 -4
- data/test/test_array.rb +35 -2
- data/test/test_base.rb +1 -1
- data/test/test_bytea.rb +3 -4
- data/test/test_datatype.rb +8 -7
- data/test/test_procedure.rb +10 -6
- data/test/test_table.rb +27 -11
- metadata +7 -4
data/lib/momomoto/base.rb
CHANGED
@@ -83,9 +83,7 @@ module Momomoto
|
|
83
83
|
varname = "@#{name}"
|
84
84
|
# define getter method
|
85
85
|
singleton.send(:define_method, name) do | *values |
|
86
|
-
if not
|
87
|
-
initialize
|
88
|
-
end
|
86
|
+
initialize if not initialized
|
89
87
|
instance_variable_get( varname )
|
90
88
|
end
|
91
89
|
end
|
@@ -99,9 +97,7 @@ module Momomoto
|
|
99
97
|
if values[0]
|
100
98
|
send( settername, values[0] )
|
101
99
|
else
|
102
|
-
if not
|
103
|
-
initialize
|
104
|
-
end
|
100
|
+
initialize if not initialized
|
105
101
|
instance_variable_get( varname )
|
106
102
|
end
|
107
103
|
end
|
@@ -147,7 +143,24 @@ module Momomoto
|
|
147
143
|
protected
|
148
144
|
|
149
145
|
# Getter and setter used for marking tables as initialized.
|
150
|
-
|
146
|
+
attr_writer :initialized
|
147
|
+
|
148
|
+
# overwrite initialized with a normal reader once it has been initialized
|
149
|
+
# to get rid of ruby warnings about @initialized not being initialized
|
150
|
+
# this also works for ruby 1.8.5 where instance_variable_defined? is not
|
151
|
+
# available
|
152
|
+
def initialized
|
153
|
+
@initialized ||= false
|
154
|
+
instance_eval do
|
155
|
+
undef :initialized
|
156
|
+
class << self
|
157
|
+
class_eval do
|
158
|
+
attr_reader :initialized
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
@initialized
|
163
|
+
end
|
151
164
|
|
152
165
|
# Guesses the schema name of the table this class works on.
|
153
166
|
def construct_schema_name( classname )
|
data/lib/momomoto/database.rb
CHANGED
@@ -182,6 +182,26 @@ module Momomoto
|
|
182
182
|
@transaction_active = false
|
183
183
|
end
|
184
184
|
|
185
|
+
# quotes and escapes the given string +input+
|
186
|
+
def self.quote( input )
|
187
|
+
PGconn.quote( input )
|
188
|
+
end
|
189
|
+
|
190
|
+
# quotes and escapes the given string +input+
|
191
|
+
def self.quote_string( input )
|
192
|
+
"E" + PGconn.quote( input )
|
193
|
+
end
|
194
|
+
|
195
|
+
# escapes the given identifier +input+
|
196
|
+
def self.quote_ident( input )
|
197
|
+
PGconn.quote_ident( input.to_s )
|
198
|
+
end
|
199
|
+
|
200
|
+
# quotes and escapes the given string +input+
|
201
|
+
def self.quote_bytea( input )
|
202
|
+
"E'#{PGconn.escape_bytea(input)}'"
|
203
|
+
end
|
204
|
+
|
185
205
|
# escapes the given string +input+
|
186
206
|
def self.escape_string( input )
|
187
207
|
PGconn.escape( input )
|
@@ -1,76 +1,23 @@
|
|
1
|
+
|
2
|
+
require 'momomoto/datatype/array/base'
|
3
|
+
require 'momomoto/datatype/array/integer'
|
4
|
+
require 'momomoto/datatype/array/text'
|
5
|
+
|
1
6
|
module Momomoto
|
2
7
|
module Datatype
|
3
8
|
|
4
9
|
# Represents the data type Array.
|
5
|
-
class Array
|
6
|
-
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
if
|
12
|
-
"
|
13
|
-
elsif input.instance_of?( ::Array )
|
14
|
-
"ARRAY[" + input.map{|m| "'" + Database.escape_string(m) + "'"}.join(',') + "]"
|
15
|
-
else
|
16
|
-
"'" + Database.escape_string(m) + "'"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# Values are filtered by this function when being set. See the
|
21
|
-
# method in the appropriate derived data type class for allowed
|
22
|
-
# values.
|
23
|
-
def filter_get( value ) # :nodoc:
|
24
|
-
case value
|
25
|
-
when ::Array then value
|
26
|
-
when nil,"" then nil
|
27
|
-
when "{}" then []
|
28
|
-
when /^\{[^"]+(,[^"]+)*\}$/
|
29
|
-
m = v.match(/^\{()\}$/)
|
30
|
-
m[1].split(',')
|
31
|
-
when /^\{"[^"]+"(,"[^"]+")*\}$/
|
32
|
-
m = v.match(/^\{()\}$/)
|
33
|
-
m[1].split(',').map{|e| e.gsub(/^"(.*)"$/, "\\1")}
|
34
|
-
else
|
35
|
-
raise Error, "Error parsing array value"
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
# Values are filtered by this function when being set. See the
|
41
|
-
# method in the appropriate derived data type class for allowed
|
42
|
-
# values.
|
43
|
-
def filter_set( value ) # :nodoc:
|
44
|
-
value = [value] unless value.instance_of?( ::Array )
|
45
|
-
value
|
46
|
-
end
|
47
|
-
|
48
|
-
# Get the default value for this Datatype.
|
49
|
-
def default_operator
|
50
|
-
"@>"
|
51
|
-
end
|
52
|
-
|
53
|
-
# This method is used when compiling the where clause. No need
|
54
|
-
# for direct use.
|
55
|
-
def compile_rule( field_name, value ) # :nodoc:
|
56
|
-
case value
|
57
|
-
when ::Array then
|
58
|
-
raise Error, "empty or nil array conditions are not allowed for #{field_name}" if value.empty? or value.member?( nil )
|
59
|
-
field_name.to_s + ' @> ' + escape(filter_set(value))
|
60
|
-
else
|
61
|
-
super
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
# Additional operators for instances of Array.
|
66
|
-
# See Base#operator_sign
|
67
|
-
def self.operator_sign( op )
|
68
|
-
case op
|
69
|
-
when :contains then '@>'
|
70
|
-
when :contained then '<@'
|
71
|
-
else
|
72
|
-
super( op )
|
10
|
+
class Array
|
11
|
+
|
12
|
+
# Creates a new instance of the special data type, setting +not_null+
|
13
|
+
# and +default+ according to the values from Information Schema.
|
14
|
+
def self.new( row = nil )
|
15
|
+
subtype = nil
|
16
|
+
if row.respond_to?( :udt_name ) && row.udt_name
|
17
|
+
subtype = row.udt_name.gsub(/^_/,"")
|
73
18
|
end
|
19
|
+
subtype ||= 'text'
|
20
|
+
Momomoto::Datatype::Array.const_get(subtype.capitalize).new( row )
|
74
21
|
end
|
75
22
|
|
76
23
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Momomoto
|
2
|
+
module Datatype
|
3
|
+
class Array
|
4
|
+
|
5
|
+
# base datatype for array types
|
6
|
+
class Base < Momomoto::Datatype::Base
|
7
|
+
|
8
|
+
# Creates a new instance of the special data type, setting +not_null+
|
9
|
+
# and +default+ according to the values from Information Schema.
|
10
|
+
def initialize( row = nil )
|
11
|
+
@not_null = row.respond_to?(:is_nullable) && row.is_nullable == "NO" ? true : false
|
12
|
+
@default = row.respond_to?(:column_default) ? row.column_default : nil
|
13
|
+
end
|
14
|
+
|
15
|
+
# Escape and quote +input+ to be saved in database.
|
16
|
+
# Returns 'NULL' if +input+ is nil or empty. Otherwise uses
|
17
|
+
# Database#quote
|
18
|
+
def escape( input )
|
19
|
+
if input.nil?
|
20
|
+
"NULL"
|
21
|
+
elsif input.instance_of?( ::Array )
|
22
|
+
if input.empty?
|
23
|
+
"'{}'::#{array_type}[]"
|
24
|
+
else
|
25
|
+
"ARRAY[" + input.map{|m| Database.quote(m)}.join(',') + "]::#{array_type}[]"
|
26
|
+
end
|
27
|
+
else
|
28
|
+
Database.quote( input )
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Values are filtered by this function when being set. See the
|
33
|
+
# method in the appropriate derived data type class for allowed
|
34
|
+
# values.
|
35
|
+
def filter_get( value ) # :nodoc:
|
36
|
+
case value
|
37
|
+
when ::Array then value
|
38
|
+
when nil,"" then nil
|
39
|
+
when "{}" then []
|
40
|
+
when /^\{("[^"]+"|[^",]+)(,("[^"]+"|[^",]+))*\}$/
|
41
|
+
m = value.match(/^\{(.*)\}$/)
|
42
|
+
values = []
|
43
|
+
m[1].gsub( /("[^"]+"|[^",]+)/ ) do | element |
|
44
|
+
if m = element.match(/^"(.*)"$/)
|
45
|
+
values << m[1]
|
46
|
+
else
|
47
|
+
values << element
|
48
|
+
end
|
49
|
+
end
|
50
|
+
values
|
51
|
+
else
|
52
|
+
raise Error, "Error parsing array value"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Values are filtered by this function when being set. See the
|
57
|
+
# method in the appropriate derived data type class for allowed
|
58
|
+
# values.
|
59
|
+
def filter_set( value ) # :nodoc:
|
60
|
+
value = [value] if value && !value.instance_of?( ::Array )
|
61
|
+
value
|
62
|
+
end
|
63
|
+
|
64
|
+
# Get the default value for this Datatype.
|
65
|
+
def default_operator
|
66
|
+
"@>"
|
67
|
+
end
|
68
|
+
|
69
|
+
# This method is used when compiling the where clause. No need
|
70
|
+
# for direct use.
|
71
|
+
def compile_rule( field_name, value ) # :nodoc:
|
72
|
+
case value
|
73
|
+
when ::Array then
|
74
|
+
raise Error, "empty or nil array conditions are not allowed for #{field_name}" if value.empty? or value.member?( nil )
|
75
|
+
field_name.to_s + ' @> ' + escape(filter_set(value))
|
76
|
+
else
|
77
|
+
super
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Additional operators for instances of Array.
|
82
|
+
# See Base#operator_sign
|
83
|
+
def self.operator_sign( op )
|
84
|
+
case op
|
85
|
+
when :contains then '@>'
|
86
|
+
when :contained then '<@'
|
87
|
+
else
|
88
|
+
super( op )
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Momomoto
|
2
|
+
module Datatype
|
3
|
+
class Array
|
4
|
+
|
5
|
+
# datatype for text arrays
|
6
|
+
class Integer < Base
|
7
|
+
|
8
|
+
def array_type
|
9
|
+
"int"
|
10
|
+
end
|
11
|
+
|
12
|
+
def filter_get( value )
|
13
|
+
value = super( value )
|
14
|
+
if value.instance_of?( ::Array )
|
15
|
+
value = value.map{|v| Integer(v)}
|
16
|
+
end
|
17
|
+
value
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
Int4 = Integer
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -52,11 +52,11 @@ module Momomoto
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# Escapes +input+ to be saved in database.
|
55
|
-
# If +input+ equals nil, NULL is returned, otherwise Database#
|
55
|
+
# If +input+ equals nil, NULL is returned, otherwise Database#quote
|
56
56
|
# is called.
|
57
57
|
# This method is overwritten to get data type-specific escaping rules.
|
58
58
|
def escape( input )
|
59
|
-
input.nil? ? "NULL" :
|
59
|
+
input.nil? ? "NULL" : Database.quote( input.to_s )
|
60
60
|
end
|
61
61
|
|
62
62
|
# This method is used when compiling the where clause. No need
|
@@ -70,6 +70,7 @@ module Momomoto
|
|
70
70
|
when :NOT_NULL then
|
71
71
|
field_name.to_s + ' IS NOT NULL'
|
72
72
|
when ::Array then
|
73
|
+
return compile_rule( field_name, value[0] ) if value.length == 1
|
73
74
|
raise Error, "empty array conditions are not allowed for #{field_name}" if value.empty?
|
74
75
|
raise Error, "nil values not allowed in compile_rule for #{field_name}" if value.member?( nil )
|
75
76
|
field_name.to_s + ' IN (' + value.map{ | v | escape(filter_set(v)) }.join(',') + ')'
|
@@ -5,10 +5,10 @@ module Momomoto
|
|
5
5
|
# This class is used for Binary Data (Byte Array).
|
6
6
|
class Bytea < Base
|
7
7
|
|
8
|
-
# Escapes +input+ using Database#
|
8
|
+
# Escapes +input+ using Database#quote_bytea or returns NULL if
|
9
9
|
# +input+ is nil.
|
10
10
|
def escape( input )
|
11
|
-
input.nil? ? "NULL" :
|
11
|
+
input.nil? ? "NULL" : Database.quote_bytea( input )
|
12
12
|
end
|
13
13
|
|
14
14
|
end
|
@@ -5,18 +5,18 @@ module Momomoto
|
|
5
5
|
class Interval < Time_without_time_zone
|
6
6
|
|
7
7
|
# Escapes +value+ before storing to database.
|
8
|
-
# +value+ can be either
|
8
|
+
# +value+ can be either
|
9
9
|
# nil, resulting in 'NULL',
|
10
|
-
# String, which is escaped using Database#
|
10
|
+
# String, which is escaped using Database#quote,
|
11
11
|
# or some Date-like format
|
12
12
|
def escape( value )
|
13
13
|
case value
|
14
14
|
when nil then 'NULL'
|
15
|
-
when String then
|
16
|
-
else
|
15
|
+
when String then Database.quote(value)
|
16
|
+
else Database.quote(value.strftime('%H:%M:%S'))
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
# Values are filtered by this method when getting them from database.
|
21
21
|
# Returns an instance of TimeInterval or nil if +value+ is nil or
|
22
22
|
# empty.
|
@@ -6,26 +6,26 @@ module Momomoto
|
|
6
6
|
|
7
7
|
# Compares two values and returns true if equal or false otherwise.
|
8
8
|
# It is used to check if a row field has been changed so that only
|
9
|
-
# changed fields are written to database.
|
9
|
+
# changed fields are written to database.
|
10
10
|
def equal( a, b )
|
11
11
|
a.to_s == b.to_s
|
12
12
|
end
|
13
13
|
|
14
14
|
# Escapes +input+ to be saved in database.
|
15
15
|
# Returns 'NULL' if +input+ is nil or empty. Otherwise escapes
|
16
|
-
# using Database#
|
16
|
+
# using Database#quote
|
17
17
|
def escape( input )
|
18
18
|
if input.nil? || input.to_s.empty?
|
19
19
|
"NULL"
|
20
20
|
else
|
21
|
-
|
21
|
+
Database.quote_string( input.to_s )
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
# Additional operators for instances of Text.
|
26
26
|
# See Base#operator_sign
|
27
27
|
#
|
28
|
-
# # Selects all posts having "surveillance" in their content field
|
28
|
+
# # Selects all posts having "surveillance" in their content field
|
29
29
|
# # while ignoring case.
|
30
30
|
# Posts.select( :content => {:ilike => 'surveillance'} )
|
31
31
|
def self.operator_sign( op )
|
@@ -9,7 +9,7 @@ module Momomoto
|
|
9
9
|
|
10
10
|
# Compares two values and returns true if equal or false otherwise.
|
11
11
|
# It is used to check if a row field has been changed so that only
|
12
|
-
# changed fields are written to database.
|
12
|
+
# changed fields are written to database.
|
13
13
|
# Escapes before comparing.
|
14
14
|
def equal( a, b )
|
15
15
|
escape(a) == escape(b)
|
@@ -20,8 +20,8 @@ module Momomoto
|
|
20
20
|
def escape( value )
|
21
21
|
case value
|
22
22
|
when nil then 'NULL'
|
23
|
-
when String then
|
24
|
-
else
|
23
|
+
when String then Database.quote(value)
|
24
|
+
else Database.quote(value.strftime('%H:%M:%S'))
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -11,8 +11,8 @@ module Momomoto
|
|
11
11
|
def escape( value )
|
12
12
|
case value
|
13
13
|
when nil then 'NULL'
|
14
|
-
when String then
|
15
|
-
else
|
14
|
+
when String then Database.quote(value)
|
15
|
+
else Database.quote(value.strftime('%Y-%m-%d %H:%M:%S'))
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
data/lib/momomoto/procedure.rb
CHANGED
@@ -29,7 +29,7 @@ module Momomoto
|
|
29
29
|
|
30
30
|
# guesses the procedure name of the procedure this class works on
|
31
31
|
def construct_procedure_name( classname ) # :nodoc:
|
32
|
-
classname.split('::').last.downcase.gsub(/[^a-z_0-9]/, '')
|
32
|
+
classname.to_s.split('::').last.downcase.gsub(/[^a-z_0-9]/, '')
|
33
33
|
end
|
34
34
|
|
35
35
|
# gets the full name of the procedure including schema if set
|
@@ -48,7 +48,7 @@ module Momomoto
|
|
48
48
|
# returns an array of hashes with the field names as keys and the datatype as values
|
49
49
|
def parameters( *p )
|
50
50
|
return self.send( :parameters=, *p ) if not p.empty?
|
51
|
-
initialize if not
|
51
|
+
initialize if not initialized
|
52
52
|
@parameters
|
53
53
|
end
|
54
54
|
|
data/lib/momomoto/table.rb
CHANGED
@@ -339,16 +339,26 @@ module Momomoto
|
|
339
339
|
else
|
340
340
|
cols = columns
|
341
341
|
end
|
342
|
-
sql = "SELECT " + cols.keys.map{ | field |
|
342
|
+
sql = "SELECT " + cols.keys.map{ | field | Database.quote_ident( field ) }.join( "," ) + " FROM "
|
343
343
|
sql += full_name
|
344
344
|
sql += compile_where( conditions )
|
345
345
|
sql += compile_order( options[:order] ) if options[:order] || default_order
|
346
|
+
sql = compile_distinct( sql, cols, options[:distinct] ) if options[:distinct]
|
346
347
|
sql += compile_limit( options[:limit] ) if options[:limit]
|
347
348
|
sql += compile_offset( options[:offset] ) if options[:offset]
|
348
|
-
|
349
|
-
|
350
|
-
|
349
|
+
sql
|
350
|
+
end
|
351
|
+
|
352
|
+
def compile_distinct( inner_sql, cols, distinct )
|
353
|
+
distinct = [distinct] unless distinct.instance_of?( Array )
|
354
|
+
distinct.each do | field |
|
355
|
+
raise CriticalError, "condition key '#{field}' not a column in table '#{table_name}'" unless columns.keys.member?( field.to_sym )
|
351
356
|
end
|
357
|
+
sql = "SELECT DISTINCT ON("
|
358
|
+
sql += distinct.map{|f| Database.quote_ident(f)}.join(',')
|
359
|
+
sql += ") "
|
360
|
+
sql += cols.keys.map{ | field | Database.quote_ident( field ) }.join(',')
|
361
|
+
sql += " FROM (#{inner_sql}) AS t1"
|
352
362
|
sql
|
353
363
|
end
|
354
364
|
|
data/test/test_array.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
|
2
2
|
class TestArray < Test::Unit::TestCase
|
3
3
|
|
4
|
-
def
|
4
|
+
def test_int_samples
|
5
5
|
c = Class.new( Momomoto::Table )
|
6
6
|
c.table_name = 'test_int_array'
|
7
|
-
[[
|
7
|
+
[[1,2,3],nil,[],[1]].each do | value |
|
8
8
|
r = c.new( :data => value )
|
9
9
|
assert_equal( value, r.data )
|
10
10
|
r.write
|
@@ -14,5 +14,38 @@ class TestArray < Test::Unit::TestCase
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
def test_text_samples
|
18
|
+
c = Class.new( Momomoto::Table )
|
19
|
+
c.table_name = 'test_text_array'
|
20
|
+
[['chunky','bacon'],nil,[],['foo']].each do | value |
|
21
|
+
r = c.new( :data => value )
|
22
|
+
assert_equal( value, r.data )
|
23
|
+
r.write
|
24
|
+
r2 = c.select(:id=>r.id).first
|
25
|
+
assert_equal( value, r2.data )
|
26
|
+
r.delete
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_escape
|
31
|
+
a = Momomoto::Datatype::Array.new
|
32
|
+
assert_equal( a.escape( '{1,2,3}' ), "'{1,2,3}'" )
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_filter_get_text
|
36
|
+
a = Momomoto::Datatype::Array::Text.new
|
37
|
+
assert_equal( a.filter_get( '{1,2,3}' ), ['1','2','3'] )
|
38
|
+
assert_equal( a.filter_get( "{',bacon,chunky}" ), ["'","bacon","chunky"] )
|
39
|
+
assert_equal( a.filter_get( '{",",bacon,chunky}' ), [",","bacon","chunky"] )
|
40
|
+
assert_raise( Momomoto::Error ) do
|
41
|
+
a.filter_get( "{\"}")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_filter_get_integer
|
46
|
+
a = Momomoto::Datatype::Array::Integer.new
|
47
|
+
assert_equal( a.filter_get( '{1,2,3}' ), [1,2,3] )
|
48
|
+
end
|
49
|
+
|
17
50
|
end
|
18
51
|
|
data/test/test_base.rb
CHANGED
@@ -28,7 +28,7 @@ class TestBase < Test::Unit::TestCase
|
|
28
28
|
t.table_name = 'person'
|
29
29
|
t.send( :initialize )
|
30
30
|
assert_equal( " WHERE person_id = '1'" , t.instance_eval do compile_where( :person_id => '1' ) end )
|
31
|
-
assert_equal( " WHERE person_id
|
31
|
+
assert_equal( " WHERE person_id = '1'" , t.instance_eval do compile_where( :person_id => ['1'] ) end )
|
32
32
|
assert_equal( " WHERE person_id IN ('1','2')" , t.instance_eval do compile_where( :person_id => ['1',2] ) end )
|
33
33
|
assert_equal( " WHERE first_name = E'1'" , t.instance_eval do compile_where( :first_name => '1' ) end )
|
34
34
|
assert_equal( " WHERE first_name = E'chu''nky'" , t.instance_eval do compile_where( :first_name => "chu'nky" ) end )
|
data/test/test_bytea.rb
CHANGED
@@ -24,10 +24,9 @@ class TestBytea < Test::Unit::TestCase
|
|
24
24
|
assert_equal( data.length, r.data.length )
|
25
25
|
assert_equal( data, r.data )
|
26
26
|
r.write
|
27
|
-
r2 = c.
|
28
|
-
assert_equal(
|
29
|
-
assert_equal( data
|
30
|
-
assert_equal( data, r2[0].data )
|
27
|
+
r2 = c.select_single(:id=>r.id)
|
28
|
+
assert_equal( data.length , r2.data.length )
|
29
|
+
assert_equal( data, r2.data )
|
31
30
|
end
|
32
31
|
|
33
32
|
end
|
data/test/test_datatype.rb
CHANGED
@@ -39,13 +39,14 @@ class TestDatatype < Test::Unit::TestCase
|
|
39
39
|
end
|
40
40
|
|
41
41
|
define_method( "test_operator_sign_#{type_name}" ) do
|
42
|
-
|
43
|
-
assert_equal( '
|
44
|
-
assert_equal( '
|
45
|
-
assert_equal( '
|
46
|
-
assert_equal( '
|
47
|
-
assert_equal( '
|
48
|
-
|
42
|
+
t = type.new
|
43
|
+
assert_equal( '<=', t.class.operator_sign( :le ) )
|
44
|
+
assert_equal( '<', t.class.operator_sign( :lt ) )
|
45
|
+
assert_equal( '>=', t.class.operator_sign( :ge ) )
|
46
|
+
assert_equal( '>', t.class.operator_sign( :gt ) )
|
47
|
+
assert_equal( '=', t.class.operator_sign( :eq ) )
|
48
|
+
assert_equal( '<>', t.class.operator_sign( :ne ) )
|
49
|
+
assert_raise( Momomoto::CriticalError ) { t.class.operator_sign( :foo ) }
|
49
50
|
end
|
50
51
|
|
51
52
|
define_method( "test_escape_#{type_name}" ) do
|
data/test/test_procedure.rb
CHANGED
@@ -39,20 +39,24 @@ class TestProcedure < Test::Unit::TestCase
|
|
39
39
|
|
40
40
|
def test_columns
|
41
41
|
p = Class.new( Momomoto::Procedure )
|
42
|
+
p.procedure_name("test_parameter_plpgsql")
|
42
43
|
p2 = Class.new( Momomoto::Procedure )
|
43
|
-
|
44
|
-
|
45
|
-
|
44
|
+
p2.procedure_name("test_parameter_plpgsql")
|
45
|
+
p.columns = { :chunky => :bacon }
|
46
|
+
p2.columns = { :bacon => :chunky }
|
47
|
+
assert_equal( {:chunky=>:bacon}, p.columns )
|
46
48
|
p.columns = :bacon
|
47
49
|
assert_equal( :bacon, p.columns )
|
48
|
-
p.columns
|
49
|
-
assert_equal( :chunky, p.columns )
|
50
|
-
assert_equal( :
|
50
|
+
p.columns = { :chunky => :bacon }
|
51
|
+
assert_equal( {:chunky=>:bacon}, p.columns )
|
52
|
+
assert_equal( {:bacon=>:chunky}, p2.columns )
|
51
53
|
end
|
52
54
|
|
53
55
|
def test_parameters
|
54
56
|
p = Class.new( Momomoto::Procedure )
|
57
|
+
p.procedure_name("test_parameter_plpgsql")
|
55
58
|
p2 = Class.new( Momomoto::Procedure )
|
59
|
+
p2.procedure_name("test_parameter_plpgsql")
|
56
60
|
p.parameters = { :chunky => :bacon }
|
57
61
|
p2.parameters = { :bacon => :chunky }
|
58
62
|
assert_equal( [{:chunky=>:bacon}], p.parameters )
|
data/test/test_table.rb
CHANGED
@@ -14,12 +14,14 @@ class TestTable < Test::Unit::TestCase
|
|
14
14
|
|
15
15
|
def test_default_order_getter
|
16
16
|
c1 = Class.new( Momomoto::Table )
|
17
|
+
c1.table_name('person')
|
17
18
|
c1.default_order = [:a,:b]
|
18
19
|
assert_equal( [:a,:b], c1.default_order )
|
19
20
|
end
|
20
21
|
|
21
22
|
def test_default_order_setter
|
22
23
|
c1 = Class.new( Momomoto::Table )
|
24
|
+
c1.table_name('person')
|
23
25
|
c1.default_order = :a
|
24
26
|
assert_equal( :a, c1.default_order )
|
25
27
|
c1.default_order = :b
|
@@ -30,12 +32,14 @@ class TestTable < Test::Unit::TestCase
|
|
30
32
|
|
31
33
|
def test_columns_getter
|
32
34
|
c1 = Class.new( Momomoto::Table )
|
35
|
+
c1.table_name('person')
|
33
36
|
c1.columns = {:a=>Momomoto::Datatype::Text}
|
34
37
|
assert_equal( {:a=>Momomoto::Datatype::Text}, c1.columns )
|
35
38
|
end
|
36
39
|
|
37
40
|
def test_columns_setter
|
38
41
|
c1 = Class.new( Momomoto::Table )
|
42
|
+
c1.table_name('person')
|
39
43
|
c1.columns = {:a=>Momomoto::Datatype::Text}
|
40
44
|
assert_equal( {:a=>Momomoto::Datatype::Text}, c1.columns )
|
41
45
|
c1.columns = {:b=>Momomoto::Datatype::Text}
|
@@ -46,6 +50,7 @@ class TestTable < Test::Unit::TestCase
|
|
46
50
|
|
47
51
|
def test_primary_key_getter
|
48
52
|
a = Class.new( Momomoto::Table )
|
53
|
+
a.table_name('person')
|
49
54
|
a.primary_keys( [:pk] )
|
50
55
|
assert_equal( [:pk], a.primary_keys )
|
51
56
|
p = Class.new( Momomoto::Table )
|
@@ -56,6 +61,7 @@ class TestTable < Test::Unit::TestCase
|
|
56
61
|
|
57
62
|
def test_primary_key_setter
|
58
63
|
a = Class.new( Momomoto::Table )
|
64
|
+
a.table_name('person')
|
59
65
|
a.primary_keys( [:pk] )
|
60
66
|
assert_equal( [:pk], a.primary_keys )
|
61
67
|
a.primary_keys= [:pk2]
|
@@ -72,26 +78,28 @@ class TestTable < Test::Unit::TestCase
|
|
72
78
|
|
73
79
|
def test_schema_name_setter
|
74
80
|
a = Class.new( Momomoto::Table )
|
81
|
+
a.table_name("person")
|
75
82
|
b = Class.new( Momomoto::Table )
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
assert_equal( :
|
83
|
+
b.table_name("person")
|
84
|
+
a.schema_name = :public
|
85
|
+
b.schema_name = :public
|
86
|
+
assert_equal( :public, a.schema_name )
|
87
|
+
assert_equal( :public, b.schema_name )
|
80
88
|
a.schema_name( :ratbert )
|
81
89
|
assert_equal( :ratbert, a.schema_name )
|
82
|
-
assert_equal( :
|
90
|
+
assert_equal( :public, b.schema_name )
|
83
91
|
end
|
84
92
|
|
85
93
|
def test_table_name_getter
|
86
94
|
t = Class.new( Momomoto::Table )
|
87
|
-
t.table_name = "
|
88
|
-
assert_equal( "
|
95
|
+
t.table_name = "person"
|
96
|
+
assert_equal( "person", t.table_name )
|
89
97
|
end
|
90
98
|
|
91
99
|
def test_table_name_setter
|
92
100
|
t = Class.new( Momomoto::Table )
|
93
|
-
t.table_name = "
|
94
|
-
assert_equal( "
|
101
|
+
t.table_name = "person"
|
102
|
+
assert_equal( "person", t.table_name )
|
95
103
|
t.table_name = "bacon"
|
96
104
|
assert_equal( "bacon", t.table_name )
|
97
105
|
t.table_name( "fox" )
|
@@ -127,7 +135,7 @@ class TestTable < Test::Unit::TestCase
|
|
127
135
|
def test_offset
|
128
136
|
p = Person.select( {}, {:limit => 1, :order => :person_id,:offset=>2})
|
129
137
|
assert_operator( 2, :<, p[0].person_id )
|
130
|
-
assert_raise( Momomoto::Error ) do
|
138
|
+
assert_raise( Momomoto::Error ) do
|
131
139
|
Person.select( {}, {:limit => 1, :order => :person_id,:offset=>'bacon'})
|
132
140
|
end
|
133
141
|
end
|
@@ -145,8 +153,16 @@ class TestTable < Test::Unit::TestCase
|
|
145
153
|
end
|
146
154
|
end
|
147
155
|
|
156
|
+
def test_distinct
|
157
|
+
p = Person.select({},{:distinct=>[:first_name,:nick_name]})
|
158
|
+
end
|
159
|
+
|
148
160
|
def test_write_columns
|
149
|
-
|
161
|
+
t = Class.new( Momomoto::Table )
|
162
|
+
t.table_name( 'person' )
|
163
|
+
p = t.select({},{:columns=>[:first_name],:limit=>1})[0]
|
164
|
+
assert( p.class.columns.member?(:first_name))
|
165
|
+
assert( p.class.columns.member?(:person_id))
|
150
166
|
p.first_name = 'test_write_columns'
|
151
167
|
p.write
|
152
168
|
p2 = Person.select_single(:person_id=>p.person_id)
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: momomoto
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.
|
7
|
-
date: 2008-01-
|
6
|
+
version: 0.1.16
|
7
|
+
date: 2008-01-21 00:00:00 +01:00
|
8
8
|
summary: Momomoto is an object relational mapper for PostgreSQL.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -60,10 +60,13 @@ files:
|
|
60
60
|
- lib/momomoto/datatype/numeric.rb
|
61
61
|
- lib/momomoto/datatype/bytea.rb
|
62
62
|
- lib/momomoto/datatype/timestamp_without_time_zone.rb
|
63
|
+
- lib/momomoto/datatype/timestamp_with_time_zone.rb
|
63
64
|
- lib/momomoto/datatype/time_with_time_zone.rb
|
64
65
|
- lib/momomoto/datatype/base.rb
|
65
66
|
- lib/momomoto/datatype/bigint.rb
|
66
|
-
- lib/momomoto/datatype/
|
67
|
+
- lib/momomoto/datatype/array/integer.rb
|
68
|
+
- lib/momomoto/datatype/array/text.rb
|
69
|
+
- lib/momomoto/datatype/array/base.rb
|
67
70
|
- sql/procedures.sql
|
68
71
|
- sql/types.sql
|
69
72
|
- sql/install.sql
|
@@ -117,5 +120,5 @@ dependencies:
|
|
117
120
|
requirements:
|
118
121
|
- - ">="
|
119
122
|
- !ruby/object:Gem::Version
|
120
|
-
version: 0.7.9.
|
123
|
+
version: 0.7.9.2008.01.09
|
121
124
|
version:
|