KirbyBase 2.6 → 2.6.1
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/README +65 -67
- data/bin/kbserver.rb +18 -18
- data/changes.txt +144 -137
- data/examples/aaa_try_this_first/kbtest.rb +237 -237
- data/examples/add_column_test/add_column_test.rb +27 -27
- data/examples/calculated_field_test/calculated_field_test.rb +51 -51
- data/examples/change_column_type_test/change_column_type_test.rb +25 -25
- data/examples/column_required_test/column_required_test.rb +44 -44
- data/examples/crosstab_test/crosstab_test.rb +100 -100
- data/examples/csv_import_test/csv_import_test.rb +31 -31
- data/examples/csv_import_test/plane.csv +11 -11
- data/examples/default_value_test/default_value_test.rb +54 -54
- data/examples/drop_column_test/drop_column_test.rb +24 -24
- data/examples/indexes_test/add_index_test.rb +46 -46
- data/examples/indexes_test/drop_index_test.rb +65 -65
- data/examples/indexes_test/index_test.rb +94 -94
- data/examples/kbserver_as_win32_service/kbserver_daemon.rb +47 -47
- data/examples/kbserver_as_win32_service/kbserverctl.rb +75 -75
- data/examples/link_many_test/link_many_test.rb +70 -70
- data/examples/lookup_field_test/lookup_field_test.rb +55 -55
- data/examples/lookup_field_test/lookup_field_test_2.rb +62 -62
- data/examples/lookup_field_test/the_hal_fulton_feature_test.rb +69 -69
- data/examples/many_to_many_test/many_to_many_test.rb +65 -65
- data/examples/memo_test/memo_test.rb +74 -74
- data/examples/record_class_test/record_class_test.rb +77 -77
- data/examples/record_class_test/record_class_test2.rb +31 -31
- data/examples/rename_column_test/rename_column_test.rb +45 -45
- data/examples/rename_table_test/rename_table_test.rb +38 -38
- data/examples/yaml_field_test/yaml_field_test.rb +47 -47
- data/kirbybaserubymanual.html +2324 -2324
- data/lib/kirbybase.rb +3907 -3880
- data/test/tc_local_table.rb +108 -108
- metadata +56 -54
@@ -1,27 +1,27 @@
|
|
1
|
-
#Test of add_column method.
|
2
|
-
|
3
|
-
require 'kirbybase'
|
4
|
-
|
5
|
-
db = KirbyBase.new
|
6
|
-
|
7
|
-
# If table exists, delete it.
|
8
|
-
db.drop_table(:plane) if db.table_exists?(:plane)
|
9
|
-
|
10
|
-
# Create a table.
|
11
|
-
plane_tbl = db.create_table(:plane, :name, :String, :speed, :Integer,
|
12
|
-
:service_date, :Date, :still_flying, :Boolean)
|
13
|
-
|
14
|
-
# Insert a bunch more records so we can have some "select" fun below.
|
15
|
-
plane_tbl.insert('Spitfire', 345, Date.new(1939,2,18), true)
|
16
|
-
plane_tbl.insert('Oscar', 361, Date.new(1943,12,31), false)
|
17
|
-
plane_tbl.insert('ME-109', 366, Date.new(1936,7,7),true)
|
18
|
-
plane_tbl.insert('JU-88', 289, Date.new(1937,1,19), false)
|
19
|
-
plane_tbl.insert('P-39', nil, nil, false)
|
20
|
-
plane_tbl.insert('Zero', 377, Date.new(1937,5,15), true)
|
21
|
-
|
22
|
-
plane_tbl.add_column(:range, {:DataType=>:Integer, :Index=>1}, :speed)
|
23
|
-
|
24
|
-
plane_tbl.update { |r| r.name == 'Spitfire' }.set(:range => 454)
|
25
|
-
|
26
|
-
puts plane_tbl.select_by_range_index { |r| r.range > 400 }.sort(:recno
|
27
|
-
).to_report
|
1
|
+
#Test of add_column method.
|
2
|
+
|
3
|
+
require 'kirbybase'
|
4
|
+
|
5
|
+
db = KirbyBase.new
|
6
|
+
|
7
|
+
# If table exists, delete it.
|
8
|
+
db.drop_table(:plane) if db.table_exists?(:plane)
|
9
|
+
|
10
|
+
# Create a table.
|
11
|
+
plane_tbl = db.create_table(:plane, :name, :String, :speed, :Integer,
|
12
|
+
:service_date, :Date, :still_flying, :Boolean)
|
13
|
+
|
14
|
+
# Insert a bunch more records so we can have some "select" fun below.
|
15
|
+
plane_tbl.insert('Spitfire', 345, Date.new(1939,2,18), true)
|
16
|
+
plane_tbl.insert('Oscar', 361, Date.new(1943,12,31), false)
|
17
|
+
plane_tbl.insert('ME-109', 366, Date.new(1936,7,7),true)
|
18
|
+
plane_tbl.insert('JU-88', 289, Date.new(1937,1,19), false)
|
19
|
+
plane_tbl.insert('P-39', nil, nil, false)
|
20
|
+
plane_tbl.insert('Zero', 377, Date.new(1937,5,15), true)
|
21
|
+
|
22
|
+
plane_tbl.add_column(:range, {:DataType=>:Integer, :Index=>1}, :speed)
|
23
|
+
|
24
|
+
plane_tbl.update { |r| r.name == 'Spitfire' }.set(:range => 454)
|
25
|
+
|
26
|
+
puts plane_tbl.select_by_range_index { |r| r.range > 400 }.sort(:recno
|
27
|
+
).to_report
|
@@ -1,51 +1,51 @@
|
|
1
|
-
# This example script shows how to specify calculated fields in a KirbyBase
|
2
|
-
# table. Calculated fields are "virtual" fields. They do not really exist
|
3
|
-
# in the table, but are calculated during a select query. However, once
|
4
|
-
# calculated, they behave just like "real" table fields.
|
5
|
-
|
6
|
-
# In this example, we will create an expenses table that holds information
|
7
|
-
# on recent purchases. The total_cost field is a calculated field. We tell
|
8
|
-
# KirbyBase how to calculate it's value, i.e. by multiplying the quantity
|
9
|
-
# field by the price field.
|
10
|
-
|
11
|
-
require 'kirbybase'
|
12
|
-
require 'date'
|
13
|
-
|
14
|
-
db = KirbyBase.new
|
15
|
-
|
16
|
-
# To run as a client in a multi-user environment, uncomment next line.
|
17
|
-
# Also, make sure kbserver.rb is running.
|
18
|
-
#db = KirbyBase.new do |d|
|
19
|
-
# d.connect_type = :client
|
20
|
-
# d.host = 'localhost'
|
21
|
-
# d.port = 44444
|
22
|
-
#end
|
23
|
-
|
24
|
-
# If table exists, delete it.
|
25
|
-
db.drop_table(:expenses) if db.table_exists?(:expenses)
|
26
|
-
|
27
|
-
# Create a table.
|
28
|
-
expenses_tbl = db.create_table(:expenses,
|
29
|
-
:transaction_date, :Date,
|
30
|
-
:description, :String,
|
31
|
-
:quantity, :Integer,
|
32
|
-
:price, :Float,
|
33
|
-
:total_cost, {:DataType=>:Float, :Calculated=>'quantity * price'}
|
34
|
-
)
|
35
|
-
|
36
|
-
# Insert a couple of expense records.
|
37
|
-
expenses_tbl.insert({:transaction_date => Date.new(2005, 9, 7),
|
38
|
-
:description => 'Pencils', :quantity => 100, :price => 0.50})
|
39
|
-
expenses_tbl.insert({:transaction_date => Date.new(2005, 9, 8),
|
40
|
-
:description => 'Books', :quantity => 3, :price => 45.0})
|
41
|
-
|
42
|
-
# Select all records and send the result to the screen in report format.
|
43
|
-
# Notice how the total_cost field for each record has been calculated for
|
44
|
-
# you by multiplying price times quantity.
|
45
|
-
puts "\nSelect all records:\n\n"
|
46
|
-
puts expenses_tbl.select.to_report
|
47
|
-
|
48
|
-
# And, you can even use a calculated field in your select condition. Here
|
49
|
-
# we are only selecting records whose total cost is greater than $100.
|
50
|
-
puts "\n\nSelect only records with a total cost greater than $100:\n\n"
|
51
|
-
puts expenses_tbl.select { |r| r.total_cost > 100.00 }.to_report
|
1
|
+
# This example script shows how to specify calculated fields in a KirbyBase
|
2
|
+
# table. Calculated fields are "virtual" fields. They do not really exist
|
3
|
+
# in the table, but are calculated during a select query. However, once
|
4
|
+
# calculated, they behave just like "real" table fields.
|
5
|
+
|
6
|
+
# In this example, we will create an expenses table that holds information
|
7
|
+
# on recent purchases. The total_cost field is a calculated field. We tell
|
8
|
+
# KirbyBase how to calculate it's value, i.e. by multiplying the quantity
|
9
|
+
# field by the price field.
|
10
|
+
|
11
|
+
require 'kirbybase'
|
12
|
+
require 'date'
|
13
|
+
|
14
|
+
db = KirbyBase.new
|
15
|
+
|
16
|
+
# To run as a client in a multi-user environment, uncomment next line.
|
17
|
+
# Also, make sure kbserver.rb is running.
|
18
|
+
#db = KirbyBase.new do |d|
|
19
|
+
# d.connect_type = :client
|
20
|
+
# d.host = 'localhost'
|
21
|
+
# d.port = 44444
|
22
|
+
#end
|
23
|
+
|
24
|
+
# If table exists, delete it.
|
25
|
+
db.drop_table(:expenses) if db.table_exists?(:expenses)
|
26
|
+
|
27
|
+
# Create a table.
|
28
|
+
expenses_tbl = db.create_table(:expenses,
|
29
|
+
:transaction_date, :Date,
|
30
|
+
:description, :String,
|
31
|
+
:quantity, :Integer,
|
32
|
+
:price, :Float,
|
33
|
+
:total_cost, {:DataType=>:Float, :Calculated=>'quantity * price'}
|
34
|
+
)
|
35
|
+
|
36
|
+
# Insert a couple of expense records.
|
37
|
+
expenses_tbl.insert({:transaction_date => Date.new(2005, 9, 7),
|
38
|
+
:description => 'Pencils', :quantity => 100, :price => 0.50})
|
39
|
+
expenses_tbl.insert({:transaction_date => Date.new(2005, 9, 8),
|
40
|
+
:description => 'Books', :quantity => 3, :price => 45.0})
|
41
|
+
|
42
|
+
# Select all records and send the result to the screen in report format.
|
43
|
+
# Notice how the total_cost field for each record has been calculated for
|
44
|
+
# you by multiplying price times quantity.
|
45
|
+
puts "\nSelect all records:\n\n"
|
46
|
+
puts expenses_tbl.select.to_report
|
47
|
+
|
48
|
+
# And, you can even use a calculated field in your select condition. Here
|
49
|
+
# we are only selecting records whose total cost is greater than $100.
|
50
|
+
puts "\n\nSelect only records with a total cost greater than $100:\n\n"
|
51
|
+
puts expenses_tbl.select { |r| r.total_cost > 100.00 }.to_report
|
@@ -1,25 +1,25 @@
|
|
1
|
-
# This script is an example of how to change a column type.
|
2
|
-
#
|
3
|
-
require 'kirbybase'
|
4
|
-
|
5
|
-
db = KirbyBase.new
|
6
|
-
|
7
|
-
# If table exists, delete it.
|
8
|
-
db.drop_table(:log) if db.table_exists?(:log)
|
9
|
-
|
10
|
-
log_tbl = db.create_table(:log, :log_timestamp, :DateTime, :msg, :String)
|
11
|
-
|
12
|
-
log_tbl.insert(DateTime.now, 'This is a log message')
|
13
|
-
log_tbl.insert(DateTime.now, 'This is a another log message')
|
14
|
-
log_tbl.insert(DateTime.now, 'This is the final log message')
|
15
|
-
|
16
|
-
p log_tbl.select
|
17
|
-
puts;puts
|
18
|
-
|
19
|
-
log_tbl.change_column_type(:log_timestamp, :String)
|
20
|
-
|
21
|
-
p log_tbl.select
|
22
|
-
puts;puts
|
23
|
-
|
24
|
-
p log_tbl.field_types
|
25
|
-
|
1
|
+
# This script is an example of how to change a column type.
|
2
|
+
#
|
3
|
+
require 'kirbybase'
|
4
|
+
|
5
|
+
db = KirbyBase.new
|
6
|
+
|
7
|
+
# If table exists, delete it.
|
8
|
+
db.drop_table(:log) if db.table_exists?(:log)
|
9
|
+
|
10
|
+
log_tbl = db.create_table(:log, :log_timestamp, :DateTime, :msg, :String)
|
11
|
+
|
12
|
+
log_tbl.insert(DateTime.now, 'This is a log message')
|
13
|
+
log_tbl.insert(DateTime.now, 'This is a another log message')
|
14
|
+
log_tbl.insert(DateTime.now, 'This is the final log message')
|
15
|
+
|
16
|
+
p log_tbl.select
|
17
|
+
puts;puts
|
18
|
+
|
19
|
+
log_tbl.change_column_type(:log_timestamp, :String)
|
20
|
+
|
21
|
+
p log_tbl.select
|
22
|
+
puts;puts
|
23
|
+
|
24
|
+
p log_tbl.field_types
|
25
|
+
|
@@ -1,44 +1,44 @@
|
|
1
|
-
# This script is an example of how to specify that a value is required for a
|
2
|
-
# column.
|
3
|
-
#
|
4
|
-
require 'kirbybase'
|
5
|
-
|
6
|
-
db = KirbyBase.new
|
7
|
-
|
8
|
-
# If table exists, delete it.
|
9
|
-
db.drop_table(:address_book) if db.table_exists?(:address_book)
|
10
|
-
|
11
|
-
# Create a table. Notice how we specify a default value for :category.
|
12
|
-
address_book_tbl = db.create_table(:address_book,
|
13
|
-
:firstname, :String, :lastname, :String, :street_address, :String,
|
14
|
-
:city, :String, :phone, :String,
|
15
|
-
:category, {:DataType=>:String, :Required=>true})
|
16
|
-
|
17
|
-
begin
|
18
|
-
# Insert a record. Notice that I am passing nil for :category. This
|
19
|
-
# will cause KirbyBase to raise an exception.
|
20
|
-
address_book_tbl.insert('Bruce', 'Wayne', '1234 Bat Cave',
|
21
|
-
'Gotham City', '111-111-1111', nil)
|
22
|
-
rescue StandardError => e
|
23
|
-
puts e
|
24
|
-
puts;puts
|
25
|
-
end
|
26
|
-
|
27
|
-
begin
|
28
|
-
# Same thing should happen if I don't even specify a value for
|
29
|
-
# :category.
|
30
|
-
address_book_tbl.insert(:firstname=>'Bruce', :lastname=>'Wayne',
|
31
|
-
:street_addres=>'1234 Bat Cave', :city=>'Gotham City',
|
32
|
-
:phone=>'111-111-1111')
|
33
|
-
rescue StandardError => e
|
34
|
-
puts e
|
35
|
-
puts;puts
|
36
|
-
end
|
37
|
-
|
38
|
-
# Now, let's turn off the required flag for :category.
|
39
|
-
address_book_tbl.change_column_required(:category, false)
|
40
|
-
|
41
|
-
# And we will attempt to add the record again.
|
42
|
-
address_book_tbl.insert('Bruce', 'Wayne', '1234 Bat Cave',
|
43
|
-
'Gotham City', '111-111-1111', nil)
|
44
|
-
|
1
|
+
# This script is an example of how to specify that a value is required for a
|
2
|
+
# column.
|
3
|
+
#
|
4
|
+
require 'kirbybase'
|
5
|
+
|
6
|
+
db = KirbyBase.new
|
7
|
+
|
8
|
+
# If table exists, delete it.
|
9
|
+
db.drop_table(:address_book) if db.table_exists?(:address_book)
|
10
|
+
|
11
|
+
# Create a table. Notice how we specify a default value for :category.
|
12
|
+
address_book_tbl = db.create_table(:address_book,
|
13
|
+
:firstname, :String, :lastname, :String, :street_address, :String,
|
14
|
+
:city, :String, :phone, :String,
|
15
|
+
:category, {:DataType=>:String, :Required=>true})
|
16
|
+
|
17
|
+
begin
|
18
|
+
# Insert a record. Notice that I am passing nil for :category. This
|
19
|
+
# will cause KirbyBase to raise an exception.
|
20
|
+
address_book_tbl.insert('Bruce', 'Wayne', '1234 Bat Cave',
|
21
|
+
'Gotham City', '111-111-1111', nil)
|
22
|
+
rescue StandardError => e
|
23
|
+
puts e
|
24
|
+
puts;puts
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
# Same thing should happen if I don't even specify a value for
|
29
|
+
# :category.
|
30
|
+
address_book_tbl.insert(:firstname=>'Bruce', :lastname=>'Wayne',
|
31
|
+
:street_addres=>'1234 Bat Cave', :city=>'Gotham City',
|
32
|
+
:phone=>'111-111-1111')
|
33
|
+
rescue StandardError => e
|
34
|
+
puts e
|
35
|
+
puts;puts
|
36
|
+
end
|
37
|
+
|
38
|
+
# Now, let's turn off the required flag for :category.
|
39
|
+
address_book_tbl.change_column_required(:category, false)
|
40
|
+
|
41
|
+
# And we will attempt to add the record again.
|
42
|
+
address_book_tbl.insert('Bruce', 'Wayne', '1234 Bat Cave',
|
43
|
+
'Gotham City', '111-111-1111', nil)
|
44
|
+
|
@@ -1,100 +1,100 @@
|
|
1
|
-
# This script demonstrates how to use crosstab functionality of a
|
2
|
-
# KirbyBase result set. A KirbyBase result set automatically has an
|
3
|
-
# equivalent transposed array whereby all of the values of a column are
|
4
|
-
# available. I call this a crosstab, but I am probably using this term
|
5
|
-
# incorrectly. Perhaps the examples below will help explain what I am
|
6
|
-
# talking about.
|
7
|
-
|
8
|
-
# In this example, we have an order table and an order_item table. Each
|
9
|
-
# record in the order table represents a customer order. The order_item
|
10
|
-
# table holds the detail items for each order. We create a one-to-many link
|
11
|
-
# between the order table and the order_item table by providing extra
|
12
|
-
# information about the order.items field when we create the order table.
|
13
|
-
|
14
|
-
require 'kirbybase'
|
15
|
-
|
16
|
-
db = KirbyBase.new
|
17
|
-
|
18
|
-
# To run as a client in a multi-user environment, uncomment next line.
|
19
|
-
# Also, make sure kbserver.rb is running.
|
20
|
-
#db = KirbyBase.new do |d|
|
21
|
-
# d.connect_type = :client
|
22
|
-
# d.host = 'localhost'
|
23
|
-
# d.port = 44444
|
24
|
-
#end
|
25
|
-
|
26
|
-
# If tables exists, delete it.
|
27
|
-
db.drop_table(:order) if db.table_exists?(:order)
|
28
|
-
db.drop_table(:order_item) if db.table_exists?(:order_item)
|
29
|
-
|
30
|
-
# Create an order item table. This is the child table to the order table.
|
31
|
-
# Make sure you create the child table BEFORE you create the parent table
|
32
|
-
# so that KirbyBase can take advantage of any indexes that you have defined.
|
33
|
-
order_item_tbl = db.create_table(:order_item,
|
34
|
-
:item_id, :Integer,
|
35
|
-
:order_id, :Integer,
|
36
|
-
:descr, :String,
|
37
|
-
:qty, :Integer,
|
38
|
-
:price, :Float,
|
39
|
-
:total, {:DataType=>:Float, :Calculated=>'qty*price'}
|
40
|
-
)
|
41
|
-
|
42
|
-
# Create an order table. We are telling KirbyBase that the items field is
|
43
|
-
# to be linked to the order_item table by comparing the order.order_id
|
44
|
-
# field to the order_item.order_id field. By specifying :Link_many, we are
|
45
|
-
# telling KirbyBase to make this a one-to-many link. The result of this is
|
46
|
-
# that when you do a select, the items field of the order table is going to
|
47
|
-
# hold a reference to a ResultSet (i.e. Array) holding all order_item
|
48
|
-
# records whose order_id field match the order_id field in the order record.
|
49
|
-
order_tbl = db.create_table(:order,
|
50
|
-
:order_id, :Integer,
|
51
|
-
:customer, :String,
|
52
|
-
:items, {:DataType=> :ResultSet, :Link_many=> [:order_id, :order_item,
|
53
|
-
:order_id]}
|
54
|
-
)
|
55
|
-
|
56
|
-
# Insert some order records.
|
57
|
-
order_tbl.insert({:order_id=>345, :customer=>'Ford'})
|
58
|
-
order_tbl.insert({:order_id=>454, :customer=>'Microsoft'})
|
59
|
-
order_tbl.insert({:order_id=>17, :customer=>'Boeing'})
|
60
|
-
|
61
|
-
# Insert some order item records.
|
62
|
-
order_item_tbl.insert(1,345,'Steel',30,19.99,nil)
|
63
|
-
order_item_tbl.insert(2,345,'Glass',5,4.15,nil)
|
64
|
-
order_item_tbl.insert(5,454,'Floppies',750000,0.5,nil)
|
65
|
-
order_item_tbl.insert(3,17,'Wheels',200,2500.0,nil)
|
66
|
-
order_item_tbl.insert(4,17,'Wings',25,1000000.0,nil)
|
67
|
-
|
68
|
-
|
69
|
-
# Print all orders. Under each order print all items in that order. Notice
|
70
|
-
# that we are able to print the total for each order because we have access
|
71
|
-
# to the entire order_items.total column of the result set. We don't have
|
72
|
-
# to loop through all of the order item result set records to add up the
|
73
|
-
# total for each order.
|
74
|
-
puts "\nPrint all orders:\n"
|
75
|
-
order_tbl.select.each do |r|
|
76
|
-
puts "\nid: %3d customer: %-10s total charge: %11.2f" % [r.order_id,
|
77
|
-
r.customer, r.items.total.inject { |sum, n| sum + n }]
|
78
|
-
|
79
|
-
r.items.each do |i|
|
80
|
-
puts "\titem: %-10s %6d * %10.2f = %11.2f" % [i.descr,
|
81
|
-
i.qty, i.price, i.total]
|
82
|
-
end
|
83
|
-
end
|
84
|
-
puts '-' * 70;puts
|
85
|
-
|
86
|
-
# You can even use the ability to access an entire column of values in your
|
87
|
-
# select statements. In this example, we only want to select those orders
|
88
|
-
# whose total charges exceeds $100,000. We can do this because we have
|
89
|
-
# access to the entire total column of the child table, order items.
|
90
|
-
puts "Print only orders whose total charge exceeds $100,000:\n"
|
91
|
-
order_tbl.select { |r| r.items.total.inject { |sum, n| sum+n } > 100000
|
92
|
-
}.each do |r|
|
93
|
-
puts "\nid: %3d customer: %-10s total charge: %11.2f" % [r.order_id,
|
94
|
-
r.customer, r.items.total.inject { |sum, n| sum + n }]
|
95
|
-
|
96
|
-
r.items.each do |i|
|
97
|
-
puts "\titem: %-10s %6d * %10.2f = %11.2f" % [i.descr,
|
98
|
-
i.qty, i.price, i.total]
|
99
|
-
end
|
100
|
-
end
|
1
|
+
# This script demonstrates how to use crosstab functionality of a
|
2
|
+
# KirbyBase result set. A KirbyBase result set automatically has an
|
3
|
+
# equivalent transposed array whereby all of the values of a column are
|
4
|
+
# available. I call this a crosstab, but I am probably using this term
|
5
|
+
# incorrectly. Perhaps the examples below will help explain what I am
|
6
|
+
# talking about.
|
7
|
+
|
8
|
+
# In this example, we have an order table and an order_item table. Each
|
9
|
+
# record in the order table represents a customer order. The order_item
|
10
|
+
# table holds the detail items for each order. We create a one-to-many link
|
11
|
+
# between the order table and the order_item table by providing extra
|
12
|
+
# information about the order.items field when we create the order table.
|
13
|
+
|
14
|
+
require 'kirbybase'
|
15
|
+
|
16
|
+
db = KirbyBase.new
|
17
|
+
|
18
|
+
# To run as a client in a multi-user environment, uncomment next line.
|
19
|
+
# Also, make sure kbserver.rb is running.
|
20
|
+
#db = KirbyBase.new do |d|
|
21
|
+
# d.connect_type = :client
|
22
|
+
# d.host = 'localhost'
|
23
|
+
# d.port = 44444
|
24
|
+
#end
|
25
|
+
|
26
|
+
# If tables exists, delete it.
|
27
|
+
db.drop_table(:order) if db.table_exists?(:order)
|
28
|
+
db.drop_table(:order_item) if db.table_exists?(:order_item)
|
29
|
+
|
30
|
+
# Create an order item table. This is the child table to the order table.
|
31
|
+
# Make sure you create the child table BEFORE you create the parent table
|
32
|
+
# so that KirbyBase can take advantage of any indexes that you have defined.
|
33
|
+
order_item_tbl = db.create_table(:order_item,
|
34
|
+
:item_id, :Integer,
|
35
|
+
:order_id, :Integer,
|
36
|
+
:descr, :String,
|
37
|
+
:qty, :Integer,
|
38
|
+
:price, :Float,
|
39
|
+
:total, {:DataType=>:Float, :Calculated=>'qty*price'}
|
40
|
+
)
|
41
|
+
|
42
|
+
# Create an order table. We are telling KirbyBase that the items field is
|
43
|
+
# to be linked to the order_item table by comparing the order.order_id
|
44
|
+
# field to the order_item.order_id field. By specifying :Link_many, we are
|
45
|
+
# telling KirbyBase to make this a one-to-many link. The result of this is
|
46
|
+
# that when you do a select, the items field of the order table is going to
|
47
|
+
# hold a reference to a ResultSet (i.e. Array) holding all order_item
|
48
|
+
# records whose order_id field match the order_id field in the order record.
|
49
|
+
order_tbl = db.create_table(:order,
|
50
|
+
:order_id, :Integer,
|
51
|
+
:customer, :String,
|
52
|
+
:items, {:DataType=> :ResultSet, :Link_many=> [:order_id, :order_item,
|
53
|
+
:order_id]}
|
54
|
+
)
|
55
|
+
|
56
|
+
# Insert some order records.
|
57
|
+
order_tbl.insert({:order_id=>345, :customer=>'Ford'})
|
58
|
+
order_tbl.insert({:order_id=>454, :customer=>'Microsoft'})
|
59
|
+
order_tbl.insert({:order_id=>17, :customer=>'Boeing'})
|
60
|
+
|
61
|
+
# Insert some order item records.
|
62
|
+
order_item_tbl.insert(1,345,'Steel',30,19.99,nil)
|
63
|
+
order_item_tbl.insert(2,345,'Glass',5,4.15,nil)
|
64
|
+
order_item_tbl.insert(5,454,'Floppies',750000,0.5,nil)
|
65
|
+
order_item_tbl.insert(3,17,'Wheels',200,2500.0,nil)
|
66
|
+
order_item_tbl.insert(4,17,'Wings',25,1000000.0,nil)
|
67
|
+
|
68
|
+
|
69
|
+
# Print all orders. Under each order print all items in that order. Notice
|
70
|
+
# that we are able to print the total for each order because we have access
|
71
|
+
# to the entire order_items.total column of the result set. We don't have
|
72
|
+
# to loop through all of the order item result set records to add up the
|
73
|
+
# total for each order.
|
74
|
+
puts "\nPrint all orders:\n"
|
75
|
+
order_tbl.select.each do |r|
|
76
|
+
puts "\nid: %3d customer: %-10s total charge: %11.2f" % [r.order_id,
|
77
|
+
r.customer, r.items.total.inject { |sum, n| sum + n }]
|
78
|
+
|
79
|
+
r.items.each do |i|
|
80
|
+
puts "\titem: %-10s %6d * %10.2f = %11.2f" % [i.descr,
|
81
|
+
i.qty, i.price, i.total]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
puts '-' * 70;puts
|
85
|
+
|
86
|
+
# You can even use the ability to access an entire column of values in your
|
87
|
+
# select statements. In this example, we only want to select those orders
|
88
|
+
# whose total charges exceeds $100,000. We can do this because we have
|
89
|
+
# access to the entire total column of the child table, order items.
|
90
|
+
puts "Print only orders whose total charge exceeds $100,000:\n"
|
91
|
+
order_tbl.select { |r| r.items.total.inject { |sum, n| sum+n } > 100000
|
92
|
+
}.each do |r|
|
93
|
+
puts "\nid: %3d customer: %-10s total charge: %11.2f" % [r.order_id,
|
94
|
+
r.customer, r.items.total.inject { |sum, n| sum + n }]
|
95
|
+
|
96
|
+
r.items.each do |i|
|
97
|
+
puts "\titem: %-10s %6d * %10.2f = %11.2f" % [i.descr,
|
98
|
+
i.qty, i.price, i.total]
|
99
|
+
end
|
100
|
+
end
|