ramen 0.4.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 (40) hide show
  1. data/doc/doc_resources/MetaData_Class_Diagram.gif +0 -0
  2. data/doc/doc_resources/MetaData_Class_Diagram.png +0 -0
  3. data/doc/doc_resources/Thumbs.db +0 -0
  4. data/lib/ramen/core.rb +75 -0
  5. data/lib/ramen/default_logger.rb +29 -0
  6. data/lib/ramen/engine/engine.rb +34 -0
  7. data/lib/ramen/engine/mysql.rb +225 -0
  8. data/lib/ramen/engine/sql2005.rb +377 -0
  9. data/lib/ramen/home.rb +162 -0
  10. data/lib/ramen/metadata/column.rb +38 -0
  11. data/lib/ramen/metadata/database.rb +137 -0
  12. data/lib/ramen/metadata/foreign_key.rb +71 -0
  13. data/lib/ramen/metadata/foreign_key_column.rb +51 -0
  14. data/lib/ramen/metadata/index.rb +71 -0
  15. data/lib/ramen/metadata/index_column.rb +49 -0
  16. data/lib/ramen/metadata/key_constraint.rb +56 -0
  17. data/lib/ramen/metadata/metadata.rb +10 -0
  18. data/lib/ramen/metadata/primary_key.rb +71 -0
  19. data/lib/ramen/metadata/primary_key_column.rb +49 -0
  20. data/lib/ramen/metadata/schema.rb +86 -0
  21. data/lib/ramen/metadata/table.rb +202 -0
  22. data/lib/ramen/ramen_error.rb +16 -0
  23. data/lib/ramen/ramen_hash.rb +143 -0
  24. data/lib/ramen/ramen_module.rb +52 -0
  25. data/lib/ramen/row_data_gateway.rb +89 -0
  26. data/lib/ramen/version.rb +16 -0
  27. data/lib/ramen.rb +62 -0
  28. data/readme.txt +159 -0
  29. data/test/config/config.yml +19 -0
  30. data/test/helper.rb +18 -0
  31. data/test/mysql_create_test_db.sql +47 -0
  32. data/test/sql2005_create_test_db.sql +45 -0
  33. data/test/test_bugs.rb +32 -0
  34. data/test/test_core.rb +63 -0
  35. data/test/test_default_logger.rb +38 -0
  36. data/test/test_home.rb +33 -0
  37. data/test/test_ramen.rb +274 -0
  38. data/test/test_ramen_hash.rb +78 -0
  39. data/test/test_ramen_module.rb +21 -0
  40. metadata +99 -0
@@ -0,0 +1,274 @@
1
+ #--
2
+ # Copyright (c) 2007 Gregory N. Houston
3
+ # See ramen.rb for license information.
4
+ #++
5
+ require 'test/unit'
6
+ require 'lib/ramen'
7
+ require 'ruby-prof'
8
+ require 'singleton'
9
+ require 'dbi'
10
+ require 'yaml'
11
+ require 'test/helper.rb'
12
+ require 'test/test_bugs'
13
+
14
+ # not a very good test suite, but even so it has proved invaluable when
15
+ # making changes to ensure everything is still working.
16
+ #
17
+ # dependencies:
18
+ # * on the AdventureWorks database which is installed by SQL Server as a demo database.
19
+ # * depends on a predefined ODBC conncetion named 'ramen_test' which connects
20
+ # to AdventureWorks
21
+ #
22
+ module Ramen
23
+ PROFILE = false
24
+
25
+ class TestDatabases
26
+ include Singleton
27
+
28
+ attr_reader :dbs, :connections
29
+ def const_get( const_name )
30
+ const_name.to_s.split('::').inject( Kernel ) { |mod, name| mod.const_get( name ) }
31
+ end
32
+
33
+ def initialize
34
+ config = Helper.load_config
35
+
36
+ @connections = Hash.new
37
+ @dbs = Hash.new
38
+
39
+ config.each do |name, settings|
40
+ @connections[name] = DBI.connect(settings['connection'])
41
+ @dbs[name] = Ramen.create( :connection => @connections[name], :sql => const_get(settings["engine"]))
42
+ end
43
+ end
44
+
45
+ def test
46
+ @dbs.keys.each do |key|
47
+ yield key, @dbs[key]
48
+ end
49
+ end
50
+
51
+ def test_with_conn
52
+ @dbs.keys.each do |key|
53
+ yield key, @dbs[key], @connections[key]
54
+ end
55
+ end
56
+ end
57
+
58
+ class Test_Ramen < Test::Unit::TestCase
59
+ include TestBugs
60
+
61
+ def setup
62
+ if PROFILE
63
+ RubyProf.start
64
+ end
65
+ end
66
+
67
+ def teardown
68
+ if PROFILE
69
+ result = RubyProf.stop
70
+ printer = RubyProf::GraphHtmlPrinter.new(result)
71
+ printer.print(open("doc/profile_#{@name}.html",'w'), 0)
72
+ end
73
+ end
74
+
75
+ def t2_list_tables( key, db, conn )
76
+ @name = "test_list_tables_#{key}"
77
+ tables = db.list_tables(conn)
78
+ result = tables.select { |e| e[1].downcase == 'employee'}
79
+ assert_equal( 1, result.length )
80
+ end
81
+
82
+ def t_table_access( key, db )
83
+ @name = "test_table_access_#{key}"
84
+
85
+ employee = db.schema['RamenTestSchema'].table['Employee']
86
+ assert_equal( 0, employee.is_published ) if employee.respond_to? :is_published #sql2005
87
+ assert_equal( 1, employee.auto_increment ) if employee.respond_to? :auto_increment # mysql
88
+
89
+ if employee.respond_to? :table_id then
90
+ employee = db.schema['RamenTestSchema'].table[employee.table_id]
91
+ assert_equal( 'Employee', employee.table_name )
92
+ end
93
+ end
94
+
95
+ def t_column_access( key, db )
96
+ @name = "test_table_column_access_#{key}"
97
+ table = db.schema['RamenTestSchema'].table['Employee']
98
+ column = table.column['LoginID']
99
+ if column.respond_to? :max_length # sql2005
100
+ assert_equal( 512, column.max_length )
101
+ elsif column.respond_to? :character_maximum_length # mysql
102
+ assert_equal( 256, column.character_maximum_length )
103
+ else
104
+ fail("dont know how to test column length, please update the test code.")
105
+ end
106
+ end
107
+
108
+ def t_foreign_key_access( key, db )
109
+ @name = "test_foreign_key_access_#{key}"
110
+ table = db.schema['RamenTestSchema'].table['Employee']
111
+ assert_equal( 'ManagerID', table.fk['FK_Employee_Employee_ManagerID'].column['ManagerID'].column_name )
112
+ end
113
+
114
+ def t_index_access( key, db )
115
+ @name = "test_index_access_#{key}"
116
+ table = db.schema['RamenTestSchema'].table['Employee']
117
+ assert_equal( 'employee', table.index['IX_Employee_LoginID'].table_name.downcase )
118
+ assert_equal( 'loginid', table.index['IX_Employee_LoginID'].column['LoginID'].column_name.downcase )
119
+ end
120
+
121
+ def t_index_nonunique_access( key, db )
122
+ @name = "test_index_nonunique_access_#{key}"
123
+ index = db.schema['RamenTestSchema'].table['Employee'].index['IX_Employee_ManagerID']
124
+ assert_equal( 'ManagerID', index.column['ManagerID'].column_name )
125
+ assert_equal( 0, index.is_unique ) if index.respond_to? :is_unique # sql 2005
126
+ assert_equal( 1, index.non_unique ) if index.respond_to? :non_unique # mysql
127
+ end
128
+
129
+ def t_primary_key_access( key, db )
130
+ @name = "test_primary_key_access_#{key}"
131
+ table = db.schema['RamenTestSchema'].table['Employee']
132
+ assert_equal( 1, table.pk.is_primary_key ) if table.pk.respond_to? :is_primary_key
133
+ assert_equal( 'employeeid', table.pk.column['EmployeeID'].column_name.downcase )
134
+ end
135
+
136
+ def t2_all( key, db, conn )
137
+ @name = "test_all_#{key}"
138
+ db.list_tables(conn).each do |record|
139
+ schema = db.schema[ record[0] ]
140
+ assert_not_nil( schema )
141
+ table = db.schema[ record[0] ].table[ record[1] ]
142
+ assert_not_nil( table )
143
+ end
144
+ end
145
+
146
+ def t_schema_by_name( key, db )
147
+ @name = "test_schema_by_name_#{key}"
148
+ assert_equal( 'ramentestschema', db.schema['RamenTestSchema'].schema_name.downcase )
149
+ end
150
+
151
+ # TODO -- support key constraints
152
+ #
153
+ # def t_key( key, db )
154
+ # @name = "test_key_#{key}"
155
+ # key = db.schema['RamenTestSchema'].table['Employee'].key['PK_Employee_EmployeeID']
156
+ # assert_not_nil( key )
157
+ # end
158
+
159
+ def t_inspect( key, db )
160
+ @name = "test_inspect_#{key}"
161
+ db_text = db.inspect
162
+ assert_match(/Database/, db_text)
163
+
164
+ schema = db.schema['RamenTestSchema'].inspect
165
+ assert_match(/Schema/, schema)
166
+ assert_match(/RamenTestSchema/i, schema)
167
+
168
+ table = db.schema['RamenTestSchema'].table['Employee'].inspect
169
+ assert_match(/Table/, table)
170
+ assert_match(/Employee /i, table)
171
+ end
172
+
173
+ def t_compare_same_type( key, db )
174
+ @name = "test_compare_#{key}"
175
+ a = db.schema['RamenTestSchema']
176
+ b = db.schema['RamenTestSchema2']
177
+ assert_equal( -1, a <=> b)
178
+ assert_equal( 1, b <=> a)
179
+ assert_equal( 0, a <=> a)
180
+ end
181
+
182
+ def t_compare_diff_type( key, db )
183
+ @name = "test_compare_diff_type_#{key}"
184
+ a = db.schema['RamenTestSchema']
185
+ b = 42
186
+ assert_equal( nil, a <=> b)
187
+ assert_equal( nil, b <=> a)
188
+ end
189
+
190
+ def t_compare_nil( key, db )
191
+ @name = "test_compare_nil_#{key}"
192
+ a = db.schema['RamenTestSchema']
193
+ b = nil
194
+ assert_equal( nil, a <=> b)
195
+ assert_equal( -1, b <=> a )
196
+ #assert_raise( NoMethodError ) { b <=> a }
197
+ end
198
+
199
+ def t_compare_row_data_gateway( key, db )
200
+ @name = "test_compare_row_data_gateway_#{key}"
201
+ a = db.schema['RamenTestSchema']
202
+ b = db.schema['RamenTestSchema'].table['Employee']
203
+ assert_equal( 1, a <=> b)
204
+ assert_equal( -1, b <=> a)
205
+ end
206
+
207
+ def t_compare_all( key, db )
208
+ @name = "test_compare_all_#{key}"
209
+ compare_helper db.schema['RamenTestSchema'], db.schema['RamenTestSchema2']
210
+ employee = db.schema['RamenTestSchema'].table['Employee']
211
+ address = db.schema['RamenTestSchema'].table['EmployeeAddress']
212
+ compare_helper employee, address
213
+ compare_helper employee.column['LoginID'], employee.column['ManagerID']
214
+ compare_helper address.fk['FK_EmployeeAddress_Employee'], employee.fk['FK_Employee_Employee_ManagerID']
215
+ compare_helper address.fk['FK_EmployeeAddress_Employee'].column['EmployeeID'], employee.fk['FK_Employee_Employee_ManagerID'].column['ManagerID']
216
+ compare_helper employee.index['IX_Employee_LoginID'], employee.index['IX_Employee_ManagerID']
217
+ compare_helper employee.index['IX_Employee_LoginID'].column['LoginID'], employee.index['IX_Employee_ManagerID'].column['ManagerID']
218
+ unless address.pk.primary_key_name == 'PRIMARY' and employee.pk.primary_key_name == 'PRIMARY' then # mysql
219
+ compare_helper address.pk, employee.pk
220
+ end
221
+ compare_helper address.pk.column['AddressID'], employee.pk.column['EmployeeID']
222
+ # compare_helper address.key['PK_EmployeeAddress_EmployeeID_AddressID'], employee.key['PK_Employee_EmployeeID']
223
+ end
224
+
225
+ def compare_helper( a, b )
226
+ msg = "#{a.inspect} #{b.inspect}"
227
+ assert_equal( -1, a <=> b, "a <=> b; #{msg}")
228
+ assert_equal( 1, b <=> a, "b <=> a; #{msg}")
229
+ assert_equal( 0, a <=> a, "a <=> a; #{msg}")
230
+ end
231
+
232
+ self.instance_methods.each do |method_name|
233
+ if method_name =~ /^t_/ then
234
+ define_method(method_name.sub(/^t_/, 'test_').to_sym) do
235
+ TestDatabases.instance.test do | key, db |
236
+ begin
237
+ self.send(method_name.to_sym, key, db)
238
+ rescue Exception => e
239
+ unless e.respond_to? :old_message
240
+ e.singleton_class.module_eval do
241
+ alias :old_message :message
242
+ define_method :message do
243
+ "#{old_message}; engine=#{key}"
244
+ end
245
+ end
246
+ end
247
+ raise
248
+ end
249
+ end
250
+ end
251
+ end
252
+
253
+ if method_name =~ /^t2_/ then
254
+ define_method(method_name.sub(/^t2_/, 'test_').to_sym) do
255
+ TestDatabases.instance.test_with_conn do | key, db, conn |
256
+ begin
257
+ self.send(method_name.to_sym, key, db, conn)
258
+ rescue Exception => e
259
+ unless e.respond_to? :old_message
260
+ e.singleton_class.module_eval do
261
+ alias :old_message :message
262
+ define_method :message do
263
+ "#{key}: #{old_message}"
264
+ end
265
+ end
266
+ end
267
+ raise
268
+ end
269
+ end
270
+ end
271
+ end
272
+ end
273
+ end
274
+ end
@@ -0,0 +1,78 @@
1
+ #--
2
+ # Copyright (c) 2007 Gregory N. Houston
3
+ # See ramen.rb for license information.
4
+ #++
5
+
6
+ require 'test/unit'
7
+ require 'lib/ramen'
8
+
9
+ module Ramen
10
+ class ObjToStoreInHash
11
+ attr_reader :obj_id, :obj_name
12
+ def initialize( id, name )
13
+ @obj_id = id
14
+ @obj_name = name
15
+ end
16
+ end
17
+
18
+ class TestRamenHash < Test::Unit::TestCase
19
+ def setup
20
+ @obj1 = ObjToStoreInHash.new( 1, 'One' )
21
+ @obj2 = ObjToStoreInHash.new( 2, 'Two' )
22
+ @collection = RamenHash.new( ObjToStoreInHash, 'obj' )
23
+ @collection.add( @obj1 )
24
+ @collection.add( @obj2 )
25
+ end
26
+
27
+ def test_hash
28
+ assert_equal(@obj1, @collection[1])
29
+ assert_equal(@obj1, @collection['One'])
30
+
31
+ assert_equal(@obj2, @collection[2])
32
+ assert_equal(@obj2, @collection['Two'])
33
+ end
34
+
35
+ def test_no_assignment
36
+ assert_raise NoMethodError do
37
+ @collection[5] = 5
38
+ end
39
+ end
40
+
41
+ def test_wrong_class
42
+ assert_raise RamenError do
43
+ @collection.add( Object.new )
44
+ end
45
+ end
46
+
47
+ def test_each_by_name
48
+ @collection.each_by_name do |name,value|
49
+ assert( (['one','two'].include? name), "name must be either one or two, name=#{name}")
50
+ assert_same( @collection[name], value )
51
+ end
52
+ end
53
+
54
+ def test_each_by_id
55
+ @collection.each_by_id do |id,value|
56
+ assert( ([1,2].include? id), "id must be either 1 or 2, id=#{id}")
57
+ assert_same( @collection[id], value )
58
+ end
59
+ end
60
+
61
+ def test_each
62
+ @collection.each do |obj|
63
+ assert( ([1,2].include? obj.obj_id), "id must be either 1 or 2, id=#{obj.obj_id}")
64
+ end
65
+ end
66
+
67
+ def test_to_s
68
+ # simply exercise to_s to ensure it doesn't throw exception
69
+ @collection.to_s
70
+ end
71
+
72
+ def test_default
73
+ assert_raise RamenError do
74
+ @collection['I-am-not-in-the-collection']
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,21 @@
1
+ #--
2
+ # Copyright (c) 2007 Gregory N. Houston
3
+ # See ramen.rb for license information.
4
+ #++
5
+ require 'test/unit'
6
+ require 'lib/ramen'
7
+ require 'dbi'
8
+
9
+ module Ramen
10
+ class TestRamenModule < Test::Unit::TestCase
11
+ def test_create_error
12
+ assert_raise RamenError do
13
+ Ramen.create( :connection => nil )
14
+ end
15
+
16
+ assert_raise RamenError do
17
+ Ramen.create()
18
+ end
19
+ end
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: ramen
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.4.0
7
+ date: 2008-03-14 00:00:00 -05:00
8
+ summary: Ramen, database reflection library. Easy access to the definition of schemas, tables, columns, indexes, and foreign keys.
9
+ require_paths:
10
+ - lib
11
+ email:
12
+ homepage: http://ramen.rubyforge.org/
13
+ rubyforge_project: ramen
14
+ description: This library provides easy access to the meta-data of a relational database. Ramen exposes Schema, Tables, Columns, Indexes, and Foreign Keys. Ramen was developed to support Noodle (also on rubyforge).
15
+ autorequire: ramen
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Gregory N. Houston
31
+ files:
32
+ - lib/ramen/core.rb
33
+ - lib/ramen/default_logger.rb
34
+ - lib/ramen/engine/engine.rb
35
+ - lib/ramen/engine/mysql.rb
36
+ - lib/ramen/engine/sql2005.rb
37
+ - lib/ramen/home.rb
38
+ - lib/ramen/metadata/column.rb
39
+ - lib/ramen/metadata/database.rb
40
+ - lib/ramen/metadata/foreign_key.rb
41
+ - lib/ramen/metadata/foreign_key_column.rb
42
+ - lib/ramen/metadata/index.rb
43
+ - lib/ramen/metadata/index_column.rb
44
+ - lib/ramen/metadata/key_constraint.rb
45
+ - lib/ramen/metadata/metadata.rb
46
+ - lib/ramen/metadata/primary_key.rb
47
+ - lib/ramen/metadata/primary_key_column.rb
48
+ - lib/ramen/metadata/schema.rb
49
+ - lib/ramen/metadata/table.rb
50
+ - lib/ramen/ramen_error.rb
51
+ - lib/ramen/ramen_hash.rb
52
+ - lib/ramen/ramen_module.rb
53
+ - lib/ramen/row_data_gateway.rb
54
+ - lib/ramen/version.rb
55
+ - lib/ramen.rb
56
+ - test/config
57
+ - test/config/config.yml
58
+ - test/helper.rb
59
+ - test/mysql_create_test_db.sql
60
+ - test/sql2005_create_test_db.sql
61
+ - test/test_bugs.rb
62
+ - test/test_core.rb
63
+ - test/test_default_logger.rb
64
+ - test/test_home.rb
65
+ - test/test_ramen.rb
66
+ - test/test_ramen_hash.rb
67
+ - test/test_ramen_module.rb
68
+ - readme.txt
69
+ - doc/doc_resources/MetaData_Class_Diagram.gif
70
+ - doc/doc_resources/MetaData_Class_Diagram.png
71
+ - doc/doc_resources/Thumbs.db
72
+ test_files:
73
+ - test/config
74
+ - test/config/config.yml
75
+ - test/helper.rb
76
+ - test/mysql_create_test_db.sql
77
+ - test/sql2005_create_test_db.sql
78
+ - test/test_bugs.rb
79
+ - test/test_core.rb
80
+ - test/test_default_logger.rb
81
+ - test/test_home.rb
82
+ - test/test_ramen.rb
83
+ - test/test_ramen_hash.rb
84
+ - test/test_ramen_module.rb
85
+ rdoc_options:
86
+ - --main
87
+ - readme.txt
88
+ - --title
89
+ - Ramen for Ruby (rdoc)
90
+ extra_rdoc_files:
91
+ - readme.txt
92
+ executables: []
93
+
94
+ extensions: []
95
+
96
+ requirements: []
97
+
98
+ dependencies: []
99
+