KirbyBase 2.6 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/README +65 -67
  2. data/bin/kbserver.rb +18 -18
  3. data/changes.txt +144 -137
  4. data/examples/aaa_try_this_first/kbtest.rb +237 -237
  5. data/examples/add_column_test/add_column_test.rb +27 -27
  6. data/examples/calculated_field_test/calculated_field_test.rb +51 -51
  7. data/examples/change_column_type_test/change_column_type_test.rb +25 -25
  8. data/examples/column_required_test/column_required_test.rb +44 -44
  9. data/examples/crosstab_test/crosstab_test.rb +100 -100
  10. data/examples/csv_import_test/csv_import_test.rb +31 -31
  11. data/examples/csv_import_test/plane.csv +11 -11
  12. data/examples/default_value_test/default_value_test.rb +54 -54
  13. data/examples/drop_column_test/drop_column_test.rb +24 -24
  14. data/examples/indexes_test/add_index_test.rb +46 -46
  15. data/examples/indexes_test/drop_index_test.rb +65 -65
  16. data/examples/indexes_test/index_test.rb +94 -94
  17. data/examples/kbserver_as_win32_service/kbserver_daemon.rb +47 -47
  18. data/examples/kbserver_as_win32_service/kbserverctl.rb +75 -75
  19. data/examples/link_many_test/link_many_test.rb +70 -70
  20. data/examples/lookup_field_test/lookup_field_test.rb +55 -55
  21. data/examples/lookup_field_test/lookup_field_test_2.rb +62 -62
  22. data/examples/lookup_field_test/the_hal_fulton_feature_test.rb +69 -69
  23. data/examples/many_to_many_test/many_to_many_test.rb +65 -65
  24. data/examples/memo_test/memo_test.rb +74 -74
  25. data/examples/record_class_test/record_class_test.rb +77 -77
  26. data/examples/record_class_test/record_class_test2.rb +31 -31
  27. data/examples/rename_column_test/rename_column_test.rb +45 -45
  28. data/examples/rename_table_test/rename_table_test.rb +38 -38
  29. data/examples/yaml_field_test/yaml_field_test.rb +47 -47
  30. data/kirbybaserubymanual.html +2324 -2324
  31. data/lib/kirbybase.rb +3907 -3880
  32. data/test/tc_local_table.rb +108 -108
  33. metadata +56 -54
@@ -1,94 +1,94 @@
1
- # This script is an example of how to use indexes in KirbyBase. Indexes
2
- # allow for faster queries on large datasets.
3
- #
4
- # To use indexes, you must first specify which fields are to be indexed.
5
- # You do this at table creation time. Both single and compound indexes can
6
- # be created. Then, when performing a select query, you simply use the
7
- # automatically created select_by_?????_index method, where ????? is
8
- # replaced by the name(s) of the indexed field(s). That's it. Everything
9
- # else concerning building and maintaing indexes is done by KirbyBase.
10
- require 'kirbybase'
11
-
12
- db = KirbyBase.new
13
-
14
- # To run as a client in a multi-user environment, uncomment next line.
15
- # Also, make sure kbserver.rb is running.
16
- #db = KirbyBase.new do |d|
17
- # d.connect_type = :client
18
- # d.host = 'localhost'
19
- # d.port = 44444
20
- #end
21
-
22
- # If table exists, delete it.
23
- db.drop_table(:address_book) if db.table_exists?(:address_book)
24
-
25
- # Here we are creating a table to hold contact info. We are going to create
26
- # two indexes. One index is going to be a compound index containing the
27
- # firstname and lastname fields. Notice how we group the firstname and
28
- # lastname fields into one index by specifying :Index=>1 for both of them.
29
- # This just tells KirbyBase that the two fields should be combined into one
30
- # compound index because they both are using the same index number. The
31
- # second index is going to be a single index containing the category field.
32
- # Since we want it to be a separate index, we simply use the next available
33
- # number, 2, as the value of it's :Index key.
34
- address_book_tbl = db.create_table(:address_book,
35
- :firstname, {:DataType=>:String, :Index=>1},
36
- :lastname, {:DataType=>:String, :Index=>1},
37
- :street_address, :String,
38
- :city, :String,
39
- :phone, :String,
40
- :category, {:DataType=>:String, :Index=>2},
41
- :age, {:DataType=>:Integer, :Index=>3}
42
- )
43
-
44
- # Insert some contact info records.
45
- address_book_tbl.insert('Bruce', 'Wayne', '1234 Bat Cave', 'Gotham City',
46
- '111-111-1111', 'Super Hero', 39)
47
- address_book_tbl.insert('Bugs', 'Bunny', '1234 Rabbit Hole', 'The Forest',
48
- '222-222-2222', 'Cartoon Character', 12)
49
- address_book_tbl.insert('George', 'Bush', '1600 Pennsylvania Ave',
50
- 'Washington', '333-333-3333', 'President', 2)
51
- address_book_tbl.insert('Silver', 'Surfer', '1234 Galaxy Way',
52
- 'Any City', '444-444-4444', 'Super Hero', 199)
53
- address_book_tbl.insert('John', 'Doe', '1234 Robin Lane', 'Detroit',
54
- '999-999-9999', nil, 54)
55
- address_book_tbl.insert(nil, 'NoFirstName', 'Nowhere Road', 'Notown',
56
- '000-000-0000', 'Nothing', nil)
57
-
58
- # Select all super heros without using the index.
59
- address_book_tbl.select { |r| r.category == 'Super Hero' }.each { |r|
60
- puts '%s %s %s' % [r.firstname, r.lastname, r.phone]
61
- }
62
- puts;puts
63
- # Now, do the same query, but use the category index. These
64
- # select_by_index methods are automatically created by KirbyBase, based on
65
- # the indexes you specified at table creation.
66
- address_book_tbl.select_by_category_index { |r|
67
- r.category == 'Super Hero' }.each { |r|
68
- puts '%s %s %s' % [r.firstname, r.lastname, r.phone]
69
- }
70
- puts;puts
71
- # Select Bugs Bunny using the firstname+lastname index.
72
- address_book_tbl.select_by_firstname_lastname_index { |r|
73
- r.firstname == 'Bugs' and r.lastname == 'Bunny'
74
- }.each { |r| puts '%s %s %s' % [r.firstname, r.lastname, r.phone] }
75
-
76
- puts;puts
77
- # Select the guy with no first name using the firstname+lastname index.
78
- address_book_tbl.select_by_firstname_lastname_index { |r|
79
- r.lastname == 'NoFirstName'
80
- }.each { |r| puts '%s %s %s' % [r.firstname, r.lastname, r.phone] }
81
-
82
- puts;puts
83
- # Select the guy with no first name using the firstname+lastname index.
84
- # This time we will explicitly say firstname should be nil
85
- address_book_tbl.select_by_firstname_lastname_index { |r|
86
- r.firstname.nil? and r.lastname == 'NoFirstName'
87
- }.each { |r| puts '%s %s %s' % [r.firstname, r.lastname, r.phone] }
88
-
89
- puts;puts
90
- address_book_tbl.select_by_age_index { |r| r.age > 30 }.each { |r|
91
- puts '%s %s %d' % [r.firstname, r.lastname, r.age] }
92
-
93
- puts;puts
94
- p address_book_tbl.field_indexes
1
+ # This script is an example of how to use indexes in KirbyBase. Indexes
2
+ # allow for faster queries on large datasets.
3
+ #
4
+ # To use indexes, you must first specify which fields are to be indexed.
5
+ # You do this at table creation time. Both single and compound indexes can
6
+ # be created. Then, when performing a select query, you simply use the
7
+ # automatically created select_by_?????_index method, where ????? is
8
+ # replaced by the name(s) of the indexed field(s). That's it. Everything
9
+ # else concerning building and maintaing indexes is done by KirbyBase.
10
+ require 'kirbybase'
11
+
12
+ db = KirbyBase.new
13
+
14
+ # To run as a client in a multi-user environment, uncomment next line.
15
+ # Also, make sure kbserver.rb is running.
16
+ #db = KirbyBase.new do |d|
17
+ # d.connect_type = :client
18
+ # d.host = 'localhost'
19
+ # d.port = 44444
20
+ #end
21
+
22
+ # If table exists, delete it.
23
+ db.drop_table(:address_book) if db.table_exists?(:address_book)
24
+
25
+ # Here we are creating a table to hold contact info. We are going to create
26
+ # two indexes. One index is going to be a compound index containing the
27
+ # firstname and lastname fields. Notice how we group the firstname and
28
+ # lastname fields into one index by specifying :Index=>1 for both of them.
29
+ # This just tells KirbyBase that the two fields should be combined into one
30
+ # compound index because they both are using the same index number. The
31
+ # second index is going to be a single index containing the category field.
32
+ # Since we want it to be a separate index, we simply use the next available
33
+ # number, 2, as the value of it's :Index key.
34
+ address_book_tbl = db.create_table(:address_book,
35
+ :firstname, {:DataType=>:String, :Index=>1},
36
+ :lastname, {:DataType=>:String, :Index=>1},
37
+ :street_address, :String,
38
+ :city, :String,
39
+ :phone, :String,
40
+ :category, {:DataType=>:String, :Index=>2},
41
+ :age, {:DataType=>:Integer, :Index=>3}
42
+ )
43
+
44
+ # Insert some contact info records.
45
+ address_book_tbl.insert('Bruce', 'Wayne', '1234 Bat Cave', 'Gotham City',
46
+ '111-111-1111', 'Super Hero', 39)
47
+ address_book_tbl.insert('Bugs', 'Bunny', '1234 Rabbit Hole', 'The Forest',
48
+ '222-222-2222', 'Cartoon Character', 12)
49
+ address_book_tbl.insert('George', 'Bush', '1600 Pennsylvania Ave',
50
+ 'Washington', '333-333-3333', 'President', 2)
51
+ address_book_tbl.insert('Silver', 'Surfer', '1234 Galaxy Way',
52
+ 'Any City', '444-444-4444', 'Super Hero', 199)
53
+ address_book_tbl.insert('John', 'Doe', '1234 Robin Lane', 'Detroit',
54
+ '999-999-9999', nil, 54)
55
+ address_book_tbl.insert(nil, 'NoFirstName', 'Nowhere Road', 'Notown',
56
+ '000-000-0000', 'Nothing', nil)
57
+
58
+ # Select all super heros without using the index.
59
+ address_book_tbl.select { |r| r.category == 'Super Hero' }.each { |r|
60
+ puts '%s %s %s' % [r.firstname, r.lastname, r.phone]
61
+ }
62
+ puts;puts
63
+ # Now, do the same query, but use the category index. These
64
+ # select_by_index methods are automatically created by KirbyBase, based on
65
+ # the indexes you specified at table creation.
66
+ address_book_tbl.select_by_category_index { |r|
67
+ r.category == 'Super Hero' }.each { |r|
68
+ puts '%s %s %s' % [r.firstname, r.lastname, r.phone]
69
+ }
70
+ puts;puts
71
+ # Select Bugs Bunny using the firstname+lastname index.
72
+ address_book_tbl.select_by_firstname_lastname_index { |r|
73
+ r.firstname == 'Bugs' and r.lastname == 'Bunny'
74
+ }.each { |r| puts '%s %s %s' % [r.firstname, r.lastname, r.phone] }
75
+
76
+ puts;puts
77
+ # Select the guy with no first name using the firstname+lastname index.
78
+ address_book_tbl.select_by_firstname_lastname_index { |r|
79
+ r.lastname == 'NoFirstName'
80
+ }.each { |r| puts '%s %s %s' % [r.firstname, r.lastname, r.phone] }
81
+
82
+ puts;puts
83
+ # Select the guy with no first name using the firstname+lastname index.
84
+ # This time we will explicitly say firstname should be nil
85
+ address_book_tbl.select_by_firstname_lastname_index { |r|
86
+ r.firstname.nil? and r.lastname == 'NoFirstName'
87
+ }.each { |r| puts '%s %s %s' % [r.firstname, r.lastname, r.phone] }
88
+
89
+ puts;puts
90
+ address_book_tbl.select_by_age_index { |r| r.age > 30 }.each { |r|
91
+ puts '%s %s %d' % [r.firstname, r.lastname, r.age] }
92
+
93
+ puts;puts
94
+ p address_book_tbl.field_indexes
@@ -1,47 +1,47 @@
1
- # Modified version of kbserver.rb for use as Windows Service.
2
-
3
- require 'kirbybase'
4
- require 'drb'
5
- require 'win32/service'
6
- include Win32
7
-
8
- OPTIONS = {}
9
-
10
- class KBServerDaemon < Daemon
11
- def initialize
12
- # NOTE: Change this line to reflect where you want the log file to
13
- # reside.
14
- @log = 'C:\logs\db_server_log.txt'
15
- begin
16
- # NOTE: Change this line to reflect where the database tables
17
- # are located.
18
- @db = KirbyBase.new do |x|
19
- x.connect_type = :server
20
- x.path = 'C:\data'
21
- end
22
- rescue Exception => e
23
- File.open(@log, "a+") { |fh| ft.puts "Error: #{e}" }
24
- service_stop
25
- end
26
- end
27
-
28
- def service_main
29
- begin
30
- # NOTE: Change this line to reflect what port you want to
31
- # listen on.
32
- DRb.start_service('druby://:44444', @db)
33
- DRb.thread.join
34
- rescue StandardError, InterrupError => e
35
- File.open(@log, "a+") { |fh| fh.puts "Error: #{e}" }
36
- service_stop
37
- end
38
- end
39
-
40
- def service_stop
41
- DRb.stop_service
42
- exit
43
- end
44
- end
45
-
46
- d = KBServerDaemon.new
47
- d.mainloop
1
+ # Modified version of kbserver.rb for use as Windows Service.
2
+
3
+ require 'kirbybase'
4
+ require 'drb'
5
+ require 'win32/service'
6
+ include Win32
7
+
8
+ OPTIONS = {}
9
+
10
+ class KBServerDaemon < Daemon
11
+ def initialize
12
+ # NOTE: Change this line to reflect where you want the log file to
13
+ # reside.
14
+ @log = 'C:\logs\db_server_log.txt'
15
+ begin
16
+ # NOTE: Change this line to reflect where the database tables
17
+ # are located.
18
+ @db = KirbyBase.new do |x|
19
+ x.connect_type = :server
20
+ x.path = 'C:\data'
21
+ end
22
+ rescue Exception => e
23
+ File.open(@log, "a+") { |fh| ft.puts "Error: #{e}" }
24
+ service_stop
25
+ end
26
+ end
27
+
28
+ def service_main
29
+ begin
30
+ # NOTE: Change this line to reflect what port you want to
31
+ # listen on.
32
+ DRb.start_service('druby://:44444', @db)
33
+ DRb.thread.join
34
+ rescue StandardError, InterrupError => e
35
+ File.open(@log, "a+") { |fh| fh.puts "Error: #{e}" }
36
+ service_stop
37
+ end
38
+ end
39
+
40
+ def service_stop
41
+ DRb.stop_service
42
+ exit
43
+ end
44
+ end
45
+
46
+ d = KBServerDaemon.new
47
+ d.mainloop
@@ -1,75 +1,75 @@
1
- # Control script for the KBServer service.
2
-
3
- require 'optparse'
4
- require 'win32/service'
5
- include Win32
6
-
7
- # You will want to change these values.
8
- kbserver_home = 'C:\kbserver'
9
- kbserver_prog = kbserver_home + '\kbserver_daemon.rb'
10
- kbserver_svc = 'KirbyBaseServerSvc'
11
- kbserver_name = 'KirbyBase Database Server'
12
-
13
- OPTIONS = {}
14
-
15
- ARGV.options do |opts|
16
- opts.on("-d", "--delete", "Delete the service") {
17
- OPTIONS[:delete] = true }
18
- opts.on("-s", "--start", "Start the service") {
19
- OPTIONS[:start] = true }
20
- opts.on("-x", "--stop", "Stop the service") {
21
- OPTIONS[:stop] = true }
22
- opts.on("-i", "--install", "Install the service") {
23
- OPTIONS[:install] = true }
24
- opts.on("-h", "--help", "Show this help message") {
25
- puts opts; exit }
26
- opts.parse!
27
- end
28
-
29
- # Install the service.
30
- if OPTIONS[:install]
31
- svc = Service.new
32
- svc.create_service do |s|
33
- s.service_name = kbserver_svc
34
- s.display_name = kbserver_name
35
- s.binary_path_name = 'c:\ruby\bin\ruby.exe ' + kbserver_prog
36
- # This is required for now - bug in win32-service
37
- s.dependencies = []
38
- end
39
- svc.close
40
- puts "KirbyBase Server service installed"
41
- end
42
-
43
- # Start the service.
44
- if OPTIONS[:start]
45
- Service.start(kbserver_svc)
46
- started = false
47
- while started == false
48
- s = Service.status(kbserver_svc)
49
- started = true if s.current_state == "running"
50
- break if started == true
51
- puts "One moment, " + s.current_state
52
- sleep 1
53
- end
54
- puts "KirbyBase Server service started"
55
- end
56
-
57
- # Stop the service.
58
- if OPTIONS[:stop]
59
- begin
60
- Service.stop(kbserver_svc)
61
- rescue
62
- end
63
- puts "KirbyBase Server service stopped"
64
- end
65
-
66
- # Delete the service. Stop it first.
67
- if OPTIONS[:delete]
68
- begin
69
- Service.stop(kbserver_svc)
70
- rescue
71
- end
72
- Service.delete(kbserver_svc)
73
- puts "KirbyBase Server service deleted"
74
- end
75
-
1
+ # Control script for the KBServer service.
2
+
3
+ require 'optparse'
4
+ require 'win32/service'
5
+ include Win32
6
+
7
+ # You will want to change these values.
8
+ kbserver_home = 'C:\kbserver'
9
+ kbserver_prog = kbserver_home + '\kbserver_daemon.rb'
10
+ kbserver_svc = 'KirbyBaseServerSvc'
11
+ kbserver_name = 'KirbyBase Database Server'
12
+
13
+ OPTIONS = {}
14
+
15
+ ARGV.options do |opts|
16
+ opts.on("-d", "--delete", "Delete the service") {
17
+ OPTIONS[:delete] = true }
18
+ opts.on("-s", "--start", "Start the service") {
19
+ OPTIONS[:start] = true }
20
+ opts.on("-x", "--stop", "Stop the service") {
21
+ OPTIONS[:stop] = true }
22
+ opts.on("-i", "--install", "Install the service") {
23
+ OPTIONS[:install] = true }
24
+ opts.on("-h", "--help", "Show this help message") {
25
+ puts opts; exit }
26
+ opts.parse!
27
+ end
28
+
29
+ # Install the service.
30
+ if OPTIONS[:install]
31
+ svc = Service.new
32
+ svc.create_service do |s|
33
+ s.service_name = kbserver_svc
34
+ s.display_name = kbserver_name
35
+ s.binary_path_name = 'c:\ruby\bin\ruby.exe ' + kbserver_prog
36
+ # This is required for now - bug in win32-service
37
+ s.dependencies = []
38
+ end
39
+ svc.close
40
+ puts "KirbyBase Server service installed"
41
+ end
42
+
43
+ # Start the service.
44
+ if OPTIONS[:start]
45
+ Service.start(kbserver_svc)
46
+ started = false
47
+ while started == false
48
+ s = Service.status(kbserver_svc)
49
+ started = true if s.current_state == "running"
50
+ break if started == true
51
+ puts "One moment, " + s.current_state
52
+ sleep 1
53
+ end
54
+ puts "KirbyBase Server service started"
55
+ end
56
+
57
+ # Stop the service.
58
+ if OPTIONS[:stop]
59
+ begin
60
+ Service.stop(kbserver_svc)
61
+ rescue
62
+ end
63
+ puts "KirbyBase Server service stopped"
64
+ end
65
+
66
+ # Delete the service. Stop it first.
67
+ if OPTIONS[:delete]
68
+ begin
69
+ Service.stop(kbserver_svc)
70
+ rescue
71
+ end
72
+ Service.delete(kbserver_svc)
73
+ puts "KirbyBase Server service deleted"
74
+ end
75
+
@@ -1,70 +1,70 @@
1
- # This script demonstrates how to link a field in the table to a subset
2
- # of records from another table (i.e. a "one to many" link in database
3
- # lingo).
4
-
5
- # In this example, we have an order table and an order_item table. Each
6
- # record in the order table represents a customer order. The order_item
7
- # table holds the detail items for each order. We create a one-to-many link
8
- # between the order table and the order_item table by providing extra
9
- # information about the order.items field when we create the order table.
10
-
11
- require 'kirbybase'
12
-
13
- db = KirbyBase.new
14
-
15
- # To run as a client in a multi-user environment, uncomment next line.
16
- # Also, make sure kbserver.rb is running.
17
- #db = KirbyBase.new do |d|
18
- # d.connect_type = :client
19
- # d.host = 'localhost'
20
- # d.port = 44444
21
- #end
22
-
23
- # If table exists, delete it.
24
- db.drop_table(:order) if db.table_exists?(:order)
25
- db.drop_table(:order_item) if db.table_exists?(:order_item)
26
-
27
- # Create an order item table. This is the child table to the order table.
28
- # Create child table before creating parent table so that KirbyBase can
29
- # take advantage of any indexes.
30
- order_item_tbl = db.create_table(:order_item,
31
- :item_id, :Integer,
32
- :order_id, :Integer,
33
- :descr, :String,
34
- :qty, :Integer,
35
- :price, :Float
36
- )
37
-
38
- # Create a table. We are telling KirbyBase that the items field is
39
- # to be linked to the order_item table by comparing the order.order_id
40
- # field to the order_item.order_id field. By specifying :Link_many, we are
41
- # telling KirbyBase to make this a one-to-many link. The result of this is
42
- # that when you do a select, the items field of the order table is going to
43
- # hold a reference to a ResultSet (i.e. Array) holding all order_item
44
- # records whose order_id field match the order_id field in the order record.
45
- order_tbl = db.create_table(:order,
46
- :order_id, :Integer,
47
- :customer, :String,
48
- :items, {:DataType=> :ResultSet, :Link_many=> [:order_id, :order_item,
49
- :order_id]}
50
- )
51
-
52
- # Insert some order records.
53
- order_tbl.insert({:order_id=>345, :customer=>'Ford'})
54
- order_tbl.insert({:order_id=>454, :customer=>'Microsoft'})
55
- order_tbl.insert({:order_id=>17, :customer=>'Boeing'})
56
-
57
- # Insert some order item records.
58
- order_item_tbl.insert(1,345,'Steel',30,19.99)
59
- order_item_tbl.insert(2,345,'Glass',5,4.15)
60
- order_item_tbl.insert(5,454,'Floppies',750000,0.5)
61
- order_item_tbl.insert(3,17,'Wheels',200,2500.0)
62
- order_item_tbl.insert(4,17,'Wings',25,1000000.0)
63
-
64
- # Print all orders. Under each order print all items in that order.
65
- order_tbl.select.each do |r|
66
- puts '%3d %s' % [r.order_id, r.customer]
67
- r.items.each { |i|
68
- puts "\t%d %15s %6d %10.2f" % [i.item_id, i.descr, i.qty, i.price]
69
- }
70
- end
1
+ # This script demonstrates how to link a field in the table to a subset
2
+ # of records from another table (i.e. a "one to many" link in database
3
+ # lingo).
4
+
5
+ # In this example, we have an order table and an order_item table. Each
6
+ # record in the order table represents a customer order. The order_item
7
+ # table holds the detail items for each order. We create a one-to-many link
8
+ # between the order table and the order_item table by providing extra
9
+ # information about the order.items field when we create the order table.
10
+
11
+ require 'kirbybase'
12
+
13
+ db = KirbyBase.new
14
+
15
+ # To run as a client in a multi-user environment, uncomment next line.
16
+ # Also, make sure kbserver.rb is running.
17
+ #db = KirbyBase.new do |d|
18
+ # d.connect_type = :client
19
+ # d.host = 'localhost'
20
+ # d.port = 44444
21
+ #end
22
+
23
+ # If table exists, delete it.
24
+ db.drop_table(:order) if db.table_exists?(:order)
25
+ db.drop_table(:order_item) if db.table_exists?(:order_item)
26
+
27
+ # Create an order item table. This is the child table to the order table.
28
+ # Create child table before creating parent table so that KirbyBase can
29
+ # take advantage of any indexes.
30
+ order_item_tbl = db.create_table(:order_item,
31
+ :item_id, :Integer,
32
+ :order_id, :Integer,
33
+ :descr, :String,
34
+ :qty, :Integer,
35
+ :price, :Float
36
+ )
37
+
38
+ # Create a table. We are telling KirbyBase that the items field is
39
+ # to be linked to the order_item table by comparing the order.order_id
40
+ # field to the order_item.order_id field. By specifying :Link_many, we are
41
+ # telling KirbyBase to make this a one-to-many link. The result of this is
42
+ # that when you do a select, the items field of the order table is going to
43
+ # hold a reference to a ResultSet (i.e. Array) holding all order_item
44
+ # records whose order_id field match the order_id field in the order record.
45
+ order_tbl = db.create_table(:order,
46
+ :order_id, :Integer,
47
+ :customer, :String,
48
+ :items, {:DataType=> :ResultSet, :Link_many=> [:order_id, :order_item,
49
+ :order_id]}
50
+ )
51
+
52
+ # Insert some order records.
53
+ order_tbl.insert({:order_id=>345, :customer=>'Ford'})
54
+ order_tbl.insert({:order_id=>454, :customer=>'Microsoft'})
55
+ order_tbl.insert({:order_id=>17, :customer=>'Boeing'})
56
+
57
+ # Insert some order item records.
58
+ order_item_tbl.insert(1,345,'Steel',30,19.99)
59
+ order_item_tbl.insert(2,345,'Glass',5,4.15)
60
+ order_item_tbl.insert(5,454,'Floppies',750000,0.5)
61
+ order_item_tbl.insert(3,17,'Wheels',200,2500.0)
62
+ order_item_tbl.insert(4,17,'Wings',25,1000000.0)
63
+
64
+ # Print all orders. Under each order print all items in that order.
65
+ order_tbl.select.each do |r|
66
+ puts '%3d %s' % [r.order_id, r.customer]
67
+ r.items.each { |i|
68
+ puts "\t%d %15s %6d %10.2f" % [i.item_id, i.descr, i.qty, i.price]
69
+ }
70
+ end