momomoto 0.1.0

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.
Files changed (65) hide show
  1. data/LICENSE +340 -0
  2. data/Rakefile +38 -0
  3. data/lib/momomoto.rb +5 -0
  4. data/lib/momomoto/base.rb +162 -0
  5. data/lib/momomoto/database.rb +179 -0
  6. data/lib/momomoto/datatype.rb +20 -0
  7. data/lib/momomoto/datatype/base.rb +78 -0
  8. data/lib/momomoto/datatype/bigint.rb +9 -0
  9. data/lib/momomoto/datatype/boolean.rb +23 -0
  10. data/lib/momomoto/datatype/bytea.rb +13 -0
  11. data/lib/momomoto/datatype/character.rb +7 -0
  12. data/lib/momomoto/datatype/character_varying.rb +7 -0
  13. data/lib/momomoto/datatype/date.rb +22 -0
  14. data/lib/momomoto/datatype/inet.rb +14 -0
  15. data/lib/momomoto/datatype/integer.rb +16 -0
  16. data/lib/momomoto/datatype/interval.rb +30 -0
  17. data/lib/momomoto/datatype/numeric.rb +17 -0
  18. data/lib/momomoto/datatype/real.rb +7 -0
  19. data/lib/momomoto/datatype/smallint.rb +7 -0
  20. data/lib/momomoto/datatype/text.rb +24 -0
  21. data/lib/momomoto/datatype/time_with_time_zone.rb +10 -0
  22. data/lib/momomoto/datatype/time_without_time_zone.rb +30 -0
  23. data/lib/momomoto/datatype/timestamp_with_time_zone.rb +7 -0
  24. data/lib/momomoto/datatype/timestamp_without_time_zone.rb +29 -0
  25. data/lib/momomoto/information_schema/columns.rb +45 -0
  26. data/lib/momomoto/information_schema/fetch_procedure_columns.rb +14 -0
  27. data/lib/momomoto/information_schema/fetch_procedure_parameters.rb +14 -0
  28. data/lib/momomoto/information_schema/key_column_usage.rb +19 -0
  29. data/lib/momomoto/information_schema/routines.rb +12 -0
  30. data/lib/momomoto/information_schema/table_constraints.rb +19 -0
  31. data/lib/momomoto/join.rb +66 -0
  32. data/lib/momomoto/momomoto.rb +10 -0
  33. data/lib/momomoto/order.rb +56 -0
  34. data/lib/momomoto/procedure.rb +129 -0
  35. data/lib/momomoto/row.rb +63 -0
  36. data/lib/momomoto/table.rb +251 -0
  37. data/sql/install.sql +10 -0
  38. data/sql/procedures.sql +54 -0
  39. data/sql/types.sql +11 -0
  40. data/test/test_base.rb +17 -0
  41. data/test/test_bigint.rb +26 -0
  42. data/test/test_boolean.rb +30 -0
  43. data/test/test_bytea.rb +35 -0
  44. data/test/test_character.rb +27 -0
  45. data/test/test_character_varying.rb +17 -0
  46. data/test/test_database.rb +63 -0
  47. data/test/test_datatype.rb +62 -0
  48. data/test/test_date.rb +50 -0
  49. data/test/test_inet.rb +27 -0
  50. data/test/test_information_schema.rb +27 -0
  51. data/test/test_integer.rb +37 -0
  52. data/test/test_interval.rb +38 -0
  53. data/test/test_join.rb +19 -0
  54. data/test/test_numeric.rb +30 -0
  55. data/test/test_procedure.rb +75 -0
  56. data/test/test_real.rb +17 -0
  57. data/test/test_row.rb +47 -0
  58. data/test/test_smallint.rb +26 -0
  59. data/test/test_table.rb +233 -0
  60. data/test/test_text.rb +25 -0
  61. data/test/test_time_with_time_zone.rb +17 -0
  62. data/test/test_time_without_time_zone.rb +40 -0
  63. data/test/test_timestamp_with_time_zone.rb +17 -0
  64. data/test/test_timestamp_without_time_zone.rb +28 -0
  65. metadata +116 -0
@@ -0,0 +1,75 @@
1
+
2
+ class TestProcedure < Test::Unit::TestCase
3
+
4
+ def test_sql_function_parameter
5
+ a = Class.new(Momomoto::Procedure)
6
+ a.procedure_name("test_parameter_sql")
7
+ assert_equal( 1, a.parameters.length )
8
+ assert_equal( [:param1], a.parameters[0].keys )
9
+ end
10
+
11
+ def test_plpqsql_function_parameter
12
+ a = Class.new(Momomoto::Procedure)
13
+ a.procedure_name("test_parameter_plpgsql")
14
+ assert_equal( 2, a.parameters.length )
15
+ assert_equal( [:param1], a.parameters[0].keys )
16
+ assert_equal( [:param2], a.parameters[1].keys )
17
+ end
18
+
19
+ def test_procedure_name
20
+ self.class.const_set( :Proc1, Class.new( Momomoto::Procedure ) )
21
+ assert_equal( 'proc1', Proc1.procedure_name )
22
+ self.class.const_set( :Proc2, Class.new( Momomoto::Procedure ) )
23
+ assert_equal( 'proc2', Proc2.procedure_name )
24
+ Proc2.procedure_name( 'proc3' )
25
+ assert_equal( 'proc3', Proc2.procedure_name )
26
+ Proc2.procedure_name = 'proc4'
27
+ assert_equal( 'proc4', Proc2.procedure_name )
28
+ assert_equal( 'proc1', Proc1.procedure_name )
29
+ end
30
+
31
+ def test_columns_fetching
32
+ p = Class.new( Momomoto::Procedure )
33
+ p.procedure_name = 'fetch_procedure_columns'
34
+ p.schema_name = 'momomoto'
35
+ assert_equal( 2, p.columns.length )
36
+ end
37
+
38
+ def test_columns
39
+ p = Class.new( Momomoto::Procedure )
40
+ p2 = Class.new( Momomoto::Procedure )
41
+ p.columns = :chunky
42
+ p2.columns = :alice
43
+ assert_equal( :chunky, p.columns )
44
+ p.columns = :bacon
45
+ assert_equal( :bacon, p.columns )
46
+ p.columns( :chunky )
47
+ assert_equal( :chunky, p.columns )
48
+ assert_equal( :alice, p2.columns )
49
+ end
50
+
51
+ def test_parameters
52
+ p = Class.new( Momomoto::Procedure )
53
+ p2 = Class.new( Momomoto::Procedure )
54
+ p.parameters = { :chunky => :bacon }
55
+ p2.parameters = { :bacon => :chunky }
56
+ assert_equal( [{:chunky=>:bacon}], p.parameters )
57
+ assert_equal( [{:bacon=>:chunky}], p2.parameters )
58
+ p.parameters( {:alice=>:bob},{:eve=>:mallory})
59
+ assert_equal( [{:alice=>:bob},{:eve=>:mallory}], p.parameters )
60
+ assert_equal( [{:bacon=>:chunky}], p2.parameters )
61
+ end
62
+
63
+ def test_call
64
+ self.class.const_set(:Test_set_returning, Class.new( Momomoto::Procedure ) )
65
+ assert_equal( "test_set_returning", Test_set_returning.procedure_name )
66
+ Test_set_returning.parameters(:person_id => Momomoto::Datatype::Integer.new)
67
+ assert_not_nil( Test_set_returning.parameters )
68
+ assert_not_nil( Test_set_returning.columns )
69
+ assert( Test_set_returning.columns.length > 1 )
70
+ Test_set_returning.call( :person_id => 5 )
71
+ Test_set_returning.call({:person_id => 5},{:person_id => 5},{:order=>:person_id,:limit=>10} )
72
+ end
73
+
74
+ end
75
+
data/test/test_real.rb ADDED
@@ -0,0 +1,17 @@
1
+
2
+ class TestReal < Test::Unit::TestCase
3
+
4
+ def test_samples
5
+ c = Class.new( Momomoto::Table )
6
+ c.table_name = 'test_real'
7
+ [nil,1.0,2.0,2.3,-1.2].each do | number |
8
+ r = c.new( :data => number )
9
+ assert_equal( number, r.data )
10
+ r.write
11
+ r2 = c.select(:id=>r.id).first
12
+ assert_equal( number, r2.data )
13
+ end
14
+ end
15
+
16
+ end
17
+
data/test/test_row.rb ADDED
@@ -0,0 +1,47 @@
1
+
2
+ class TestRow < Test::Unit::TestCase
3
+
4
+ class Person < Momomoto::Table; end
5
+
6
+ def test_table
7
+ Momomoto::Information_schema::Columns.select(:table_schema => 'pg_catalog', :table_name => 'pg_tables')
8
+ Momomoto::Information_schema::Key_column_usage.select(:table_schema => 'pg_catalog', :table_name => 'pg_class')
9
+ assert_equal( Momomoto::Information_schema::Columns, Momomoto::Information_schema::Columns::Row.table )
10
+ assert_equal( Momomoto::Information_schema::Key_column_usage, Momomoto::Information_schema::Key_column_usage::Row.table )
11
+ end
12
+
13
+ def test_inheritence
14
+ self.class.const_set( :Event, Class.new( Momomoto::Table ) )
15
+ Event.const_set( :Row, Class.new )
16
+ assert_raise( Momomoto::CriticalError ) do Event.select end
17
+ end
18
+
19
+ def test_setter
20
+ a = Class.new( Momomoto::Table )
21
+ a.table_name = 'person'
22
+ r = a.select_or_new( :person_id => 13 )
23
+ r.write
24
+ assert_raise( Momomoto::Error ) do r.person_id = 14 end
25
+ end
26
+
27
+ def test_bracket
28
+ a = Person.new
29
+ assert_nil( a.person_id )
30
+ assert_equal( a.person_id, a[:person_id])
31
+ assert_equal( a.person_id, a['person_id'])
32
+ a.person_id = 23
33
+ assert_equal( 23, a.person_id)
34
+ assert_equal( a.person_id, a[:person_id])
35
+ assert_equal( a.person_id, a['person_id'])
36
+ a[:person_id] = 42
37
+ assert_equal( 42, a.person_id)
38
+ assert_equal( a.person_id, a[:person_id])
39
+ assert_equal( a.person_id, a['person_id'])
40
+ a['person_id'] = 5
41
+ assert_equal( 5, a.person_id)
42
+ assert_equal( a.person_id, a[:person_id])
43
+ assert_equal( a.person_id, a['person_id'])
44
+ end
45
+
46
+ end
47
+
@@ -0,0 +1,26 @@
1
+
2
+ class TestSmallint < Test::Unit::TestCase
3
+
4
+ def test_samples
5
+ c = Class.new( Momomoto::Table )
6
+ c.table_name = 'test_smallint'
7
+ [nil,1,2,32767].each do | number |
8
+ r = c.new( :data => number )
9
+ assert_equal( number, r.data )
10
+ r.write
11
+ r2 = c.select(:id=>r.id).first
12
+ assert_equal( number, r2.data )
13
+ end
14
+ end
15
+
16
+ def test_compile_rule
17
+ t = Momomoto::Datatype::Smallint.new
18
+ input = [ 1, '1', [1], ['1'], [1,2,3],['1','2','3'], {:eq=>1}, {:eq=>'1'}, {:lt=>10, :gt=>5}, {:lt=>'10', :gt=>'5'} ]
19
+
20
+ input.each do | test_input |
21
+ assert_instance_of( String, t.compile_rule( :field, test_input ) )
22
+ end
23
+ end
24
+
25
+ end
26
+
@@ -0,0 +1,233 @@
1
+
2
+ class TestTable < Test::Unit::TestCase
3
+
4
+ class Person < Momomoto::Table
5
+ def self.person_id=( row , newvalue )
6
+ newvalue
7
+ end
8
+
9
+ def self.nick_name=( row, newvalue )
10
+ row.first_name + newvalue
11
+ end
12
+ end
13
+
14
+ class Conference < Momomoto::Table
15
+ end
16
+
17
+ def test_columns_getter
18
+ c1 = Class.new( Momomoto::Table )
19
+ c1.columns = {:a=>Momomoto::Datatype::Text}
20
+ assert_equal( {:a=>Momomoto::Datatype::Text}, c1.columns )
21
+ end
22
+
23
+ def test_columns_setter
24
+ c1 = Class.new( Momomoto::Table )
25
+ c1.columns = {:a=>Momomoto::Datatype::Text}
26
+ assert_equal( {:a=>Momomoto::Datatype::Text}, c1.columns )
27
+ c1.columns = {:b=>Momomoto::Datatype::Text}
28
+ assert_equal( {:b=>Momomoto::Datatype::Text}, c1.columns )
29
+ c1.columns({:c=>Momomoto::Datatype::Text})
30
+ assert_equal( {:c=>Momomoto::Datatype::Text}, c1.columns )
31
+ end
32
+
33
+ def test_primary_key_getter
34
+ a = Class.new( Momomoto::Table )
35
+ a.primary_keys( [:pk] )
36
+ assert_equal( [:pk], a.primary_keys )
37
+ p = Class.new( Momomoto::Table )
38
+ p.table_name = 'person'
39
+ p.schema_name = 'public'
40
+ assert_nothing_raised do p.primary_keys end
41
+ end
42
+
43
+ def test_primary_key_setter
44
+ a = Class.new( Momomoto::Table )
45
+ a.primary_keys( [:pk] )
46
+ assert_equal( [:pk], a.primary_keys )
47
+ a.primary_keys= [:pk2]
48
+ assert_equal( [:pk2], a.primary_keys )
49
+ end
50
+
51
+ def test_schema_name_getter
52
+ self.class.const_set( :S, Class.new( Momomoto::Table ) )
53
+ assert_equal( 'public', S.schema_name )
54
+ S.schema_name = "chunky"
55
+ assert_equal( "chunky", S.schema_name )
56
+ end
57
+
58
+ def test_schema_name_setter
59
+ a = Class.new( Momomoto::Table )
60
+ b = Class.new( Momomoto::Table )
61
+ a.schema_name = :chunky
62
+ b.schema_name = :bacon
63
+ assert_equal( :chunky, a.schema_name )
64
+ assert_equal( :bacon, b.schema_name )
65
+ a.schema_name( :ratbert )
66
+ assert_equal( :ratbert, a.schema_name )
67
+ assert_equal( :bacon, b.schema_name )
68
+ end
69
+
70
+ def test_table_name_getter
71
+ t = Class.new( Momomoto::Table )
72
+ t.table_name = "chunky"
73
+ assert_equal( "chunky", t.table_name )
74
+ end
75
+
76
+ def test_table_name_setter
77
+ t = Class.new( Momomoto::Table )
78
+ t.table_name = "chunky"
79
+ assert_equal( "chunky", t.table_name )
80
+ t.table_name = "bacon"
81
+ assert_equal( "bacon", t.table_name )
82
+ t.table_name( "fox" )
83
+ assert_equal( "fox", t.table_name )
84
+ end
85
+
86
+ def test_full_name
87
+ a = Class.new( Momomoto::Table )
88
+ a.table_name( 'abc' )
89
+ assert_equal( 'public.abc', a.full_name )
90
+ a.schema_name( 'def' )
91
+ assert_equal( 'def.abc', a.full_name )
92
+ end
93
+
94
+ def test_custom_setter
95
+ p = Person.new
96
+ p.first_name = 'bacon'
97
+ p.nick_name = 'abc'
98
+ assert_equal( p.first_name + 'abc', p.nick_name )
99
+ end
100
+
101
+ def test_new
102
+ anonymous = Person.new
103
+ assert_equal(Person::Row, anonymous.class)
104
+ assert_equal( true, anonymous.new_record? )
105
+ assert_nil( anonymous.first_name )
106
+ sven = Person.new(:first_name=>'Sven',:last_name=>'Klemm')
107
+ assert_equal( 'Klemm', sven.last_name )
108
+ assert_equal( 'Sven', sven.first_name )
109
+ assert_equal( true, sven.new_record? )
110
+ end
111
+
112
+ def test_select
113
+ r = Person.select( nil, {:limit => 3})
114
+ assert_equal( 3, r.length )
115
+ Person.select( nil, {:limit => 3, :order => :person_id})
116
+ Person.select( nil, {:limit => 3, :order => "person_id"})
117
+ Person.select( nil, {:limit => 3, :order => ["person_id"]})
118
+ Person.select( nil, {:limit => 3, :order => [:first_name, :last_name]} )
119
+ Person.select( nil, {:limit => 3, :order => ['first_name', :last_name]} )
120
+ Person.select( nil, {:limit => 3, :order => ['first_name', 'last_name']} )
121
+ Person.select( nil, {:order => Momomoto::lower(:first_name)})
122
+ Person.select( nil, {:order => Momomoto::lower(:first_name, :last_name)})
123
+ Person.select( nil, {:order => Momomoto::asc( [:first_name, :last_name] )} )
124
+ Person.select( nil, {:order => [:first_name, Momomoto::lower(:last_name )]} )
125
+ Person.select( nil, {:order => [:first_name, Momomoto::desc(:last_name )]} )
126
+ Person.select( nil, {:order => Momomoto::asc(Momomoto::lower(:first_name))})
127
+ Person.select( nil, {:order => Momomoto::desc(Momomoto::lower(:first_name))})
128
+ assert_raise( Momomoto::Error ) do
129
+ Person.select( nil, {:order => Momomoto::lower(Momomoto::asc(:first_name))})
130
+ end
131
+ assert_raise( Momomoto::Error ) do
132
+ Person.select( nil, {:order => Momomoto::lower(Momomoto::desc(:first_name))})
133
+ end
134
+ assert_raise( Momomoto::Error ) do
135
+ Person.select( nil, {:limit=>'4f4'} )
136
+ end
137
+ assert_raise( Momomoto::Error ) do
138
+ Person.select( nil, {:order=>:chunky})
139
+ end
140
+ assert_raise( Momomoto::Error ) do
141
+ Person.select( nil, {:order=>[:chunky,:bacon]})
142
+ end
143
+ assert_raise( Momomoto::Error ) do
144
+ Person.select( nil, {:order=>Object.new})
145
+ end
146
+ assert_raise( Momomoto::Error ) do
147
+ Person.select( nil, {:order=>[Object.new, Object.new]})
148
+ end
149
+ end
150
+
151
+ def test_select_or_new
152
+ r = Person.select_or_new({:person_id => 7})
153
+ r.first_name = 'Sven'
154
+ r.write
155
+ assert_equal( 1, Person.select(:person_id => 7).length )
156
+ r.delete
157
+ assert_equal( 0, Person.select(:person_id => 7).length )
158
+ r2 = Person.select_or_new do | field_name |
159
+ assert( Person.columns.keys.member?( field_name ))
160
+ r.send( field_name )
161
+ end
162
+ r2.write
163
+ assert_equal( 1, Person.select(:person_id => 7).length )
164
+ r2.delete
165
+ assert_equal( 0, Person.select(:person_id => 7).length )
166
+ end
167
+
168
+ def test_select_single
169
+ # delete existing test_select_single entries
170
+ Person.select(:first_name=>'test_select_single').each do | p | p.delete end
171
+
172
+ assert_raise( Momomoto::Nothing_found ) do
173
+ Person.select_single(:first_name=>'test_select_single')
174
+ end
175
+
176
+ p1 = Person.new(:first_name=>'test_select_single')
177
+ p1.write
178
+ p2 = Person.new(:first_name=>'test_select_single')
179
+ p2.write
180
+
181
+ assert_raise( Momomoto::Too_many_records ) do
182
+ Person.select_single(:first_name=>'test_select_single')
183
+ end
184
+ p1.delete
185
+ p2.delete
186
+ end
187
+
188
+ def test_defaults
189
+ conf = Conference.select_or_new(:conference_id=>1)
190
+ conf.acronym = 'Pentabarf'
191
+ conf.title = 'Pentabarf Developer Conference'
192
+ conf.start_date = '2007-08-07'
193
+ conf.write
194
+ end
195
+
196
+ def test_write
197
+ r = Person.new
198
+ r.first_name = 'Chunky'
199
+ r.last_name = 'Bacon'
200
+ r.write
201
+ assert_not_nil( r.person_id )
202
+ assert_nothing_raised do
203
+ r.delete
204
+ r.write
205
+ r.delete
206
+ end
207
+ end
208
+
209
+ def test_write2
210
+ self.class.const_set(:Test_nodefault, Class.new( Momomoto::Table ) )
211
+ Test_nodefault.schema_name = nil
212
+ a = Test_nodefault.new
213
+ a.data = 'chunky bacon'
214
+ assert_equal( [:id], Test_nodefault.primary_keys )
215
+ assert_raise( Momomoto::Error ) do
216
+ a.write
217
+ end
218
+ end
219
+
220
+ def test_dirty
221
+ r = Person.new
222
+ assert_equal( false, r.dirty?, "New empty rows should not be dirty" )
223
+ r.first_name = 'Chunky'
224
+ assert_equal( true, r.dirty?, "Modified rows must be dirty" )
225
+ r.write
226
+ assert_equal( false, r.dirty?, "Written rows should not be dirty" )
227
+ r.delete
228
+ r = Person.new(:first_name => 'Chunky')
229
+ assert_equal( true, r.dirty? )
230
+ end
231
+
232
+ end
233
+
data/test/test_text.rb ADDED
@@ -0,0 +1,25 @@
1
+
2
+ class TestText < Test::Unit::TestCase
3
+
4
+ def test_samples
5
+ c = Class.new( Momomoto::Table )
6
+ c.table_name = 'test_text'
7
+ [nil,'a',"'","''","\\","a'b"].each do | value |
8
+ r = c.new( :data => value )
9
+ assert_equal( value, r.data )
10
+ r.write
11
+ r2 = c.select(:id=>r.id).first
12
+ assert_equal( value, r2.data )
13
+ r.delete
14
+ end
15
+ end
16
+
17
+ def test_operator_sign
18
+ type = Momomoto::Datatype::Text
19
+ assert_equal( 'LIKE', type.operator_sign( :like ) )
20
+ assert_equal( 'ILIKE', type.operator_sign( :ilike ) )
21
+ assert_raise( Momomoto::CriticalError ) { type.operator_sign( :foo ) }
22
+ end
23
+
24
+ end
25
+
@@ -0,0 +1,17 @@
1
+
2
+ class TestTimeWithTimeZone < Test::Unit::TestCase
3
+
4
+ def test_samples
5
+ c = Class.new( Momomoto::Table )
6
+ c.table_name = 'test_time_with_time_zone'
7
+ [Time.parse("00:00:00"),Time.parse("01:00:00"),Time.parse("23:00")].each do | value |
8
+ r = c.new( :data => value )
9
+ assert_equal( value, r.data )
10
+ r.write
11
+ r2 = c.select(:id=>r.id).first
12
+ assert_equal( value, r2.data )
13
+ end
14
+ end
15
+
16
+ end
17
+