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 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 instance_variable_defined?( varname )
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 instance_variable_defined?( varname )
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
- attr_accessor :initialized
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 )
@@ -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 < Base
6
-
7
- # Escapes +input+ to be saved in database.
8
- # Returns 'NULL' if +input+ is nil or empty. Otherwise escapes
9
- # using Database#escape_string
10
- def escape( input )
11
- if input.nil?
12
- "NULL"
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
+
@@ -0,0 +1,16 @@
1
+ module Momomoto
2
+ module Datatype
3
+ class Array
4
+
5
+ # datatype for text arrays
6
+ class Text < Base
7
+
8
+ def array_type
9
+ "text"
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -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#escape_string
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" : "'" + Database.escape_string( input.to_s ) + "'"
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#escape_bytea or returns NULL if
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" : "E'" + Database.escape_bytea( input ) + "'"
11
+ input.nil? ? "NULL" : Database.quote_bytea( input )
12
12
  end
13
13
 
14
14
  end
@@ -17,10 +17,10 @@ module Momomoto
17
17
  when String then ::Date.parse( value, '%Y-%m-%d' )
18
18
  else raise Error
19
19
  end
20
- rescue => e
20
+ rescue => e
21
21
  raise ConversionError, "parse Error in Date #{e}"
22
22
  end
23
-
23
+
24
24
  end
25
25
  end
26
26
  end
@@ -12,7 +12,7 @@ module Momomoto
12
12
  else value
13
13
  end
14
14
  end
15
-
15
+
16
16
  end
17
17
  end
18
18
  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#escape_string,
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 "'#{Database.escape_string(value)}'"
16
- else "'#{Database.escape_string(value.strftime('%H:%M:%S'))}'"
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.
@@ -1,9 +1,9 @@
1
1
  module Momomoto
2
2
  module Datatype
3
-
3
+
4
4
  # Represents the data type Real
5
5
  class Real < Numeric
6
-
6
+
7
7
  end
8
8
  end
9
9
  end
@@ -3,7 +3,7 @@ module Momomoto
3
3
 
4
4
  # Represents the data type Smallint
5
5
  class Smallint < Integer
6
-
6
+
7
7
  end
8
8
  end
9
9
  end
@@ -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#escape_string
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
- "E'" + Database.escape_string( input.to_s ) + "'"
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 "'#{Database.escape_string(value)}'"
24
- else "'#{Database.escape_string(value.strftime('%H:%M:%S'))}'"
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 "'#{Database.escape_string(value)}'"
15
- else "'#{Database.escape_string(value.strftime('%Y-%m-%d %H:%M:%S'))}'"
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
 
@@ -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 instance_variable_defined?( :@parameters )
51
+ initialize if not initialized
52
52
  @parameters
53
53
  end
54
54
 
@@ -339,16 +339,26 @@ module Momomoto
339
339
  else
340
340
  cols = columns
341
341
  end
342
- sql = "SELECT " + cols.keys.map{ | field | '"' + field.to_s + '"' }.join( "," ) + " FROM "
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
- if options[:distinct]
349
- raise CriticalError, "condition key '#{options[:distinct]}' not a column in table '#{table_name}'" unless columns.keys.member?( options[:distinct])
350
- sql = "SELECT DISTINCT ON(\"#{options[:distinct]}\") " + cols.keys.map{ | field | '"' + field.to_s + '"' }.join( "," ) + " FROM (#{sql}) AS t1"
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 test_samples
4
+ def test_int_samples
5
5
  c = Class.new( Momomoto::Table )
6
6
  c.table_name = 'test_int_array'
7
- [["1","2","3"],nil].each do | value |
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 IN ('1')" , t.instance_eval do compile_where( :person_id => ['1'] ) end )
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.select(:id=>r.id)
28
- assert_equal( 1, r2.length )
29
- assert_equal( data.length , r2[0].data.length )
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
@@ -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
- assert_equal( '<=', type.operator_sign( :le ) )
43
- assert_equal( '<', type.operator_sign( :lt ) )
44
- assert_equal( '>=', type.operator_sign( :ge ) )
45
- assert_equal( '>', type.operator_sign( :gt ) )
46
- assert_equal( '=', type.operator_sign( :eq ) )
47
- assert_equal( '<>', type.operator_sign( :ne ) )
48
- assert_raise( Momomoto::CriticalError ) { type.operator_sign( :foo ) }
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
@@ -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
- p.columns = :chunky
44
- p2.columns = :alice
45
- assert_equal( :chunky, p.columns )
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( :chunky )
49
- assert_equal( :chunky, p.columns )
50
- assert_equal( :alice, p2.columns )
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
- a.schema_name = :chunky
77
- b.schema_name = :bacon
78
- assert_equal( :chunky, a.schema_name )
79
- assert_equal( :bacon, b.schema_name )
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( :bacon, b.schema_name )
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 = "chunky"
88
- assert_equal( "chunky", t.table_name )
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 = "chunky"
94
- assert_equal( "chunky", t.table_name )
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
- p = Person.select({},{:columns=>[:first_name],:limit=>1})[0]
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.15
7
- date: 2008-01-13 00:00:00 +01:00
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/timestamp_with_time_zone.rb
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.2007.12.12
123
+ version: 0.7.9.2008.01.09
121
124
  version: