From 52462d141e95635fcbf692d6e2c7de2236aa6d5d Mon Sep 17 00:00:00 2001 From: Philippe PITTOLI Date: Thu, 9 May 2024 12:18:46 +0200 Subject: [PATCH] Proper Car database and functions. --- spec/cars.cr | 78 +++++++++++++++++++++++++++++++++++++++++++ spec/spec-database.cr | 50 +++++++++++++++++++++++++++ spec/test-data.cr | 21 ------------ spec/test.cr | 59 +++++++++++++------------------- 4 files changed, 152 insertions(+), 56 deletions(-) create mode 100644 spec/cars.cr create mode 100644 spec/spec-database.cr diff --git a/spec/cars.cr b/spec/cars.cr new file mode 100644 index 0000000..f65c52c --- /dev/null +++ b/spec/cars.cr @@ -0,0 +1,78 @@ +# This file contains all the necessary code to perform tests based on the following Car database. + +require "json" +require "../src/dodb.cr" +require "./spec-database.cr" + +class Car + include JSON::Serializable + + property name : String # unique to each instance (1-1 relations) + property color : String # a simple attribute (1-n relations) + property keywords : Array(String) # tags about a car, example: "shiny" (n-n relations) + + def_clone + + def initialize(@name, @color, @keywords) + end + class_getter cars = [ + Car.new("Corvet", "red", [ "shiny", "impressive", "fast", "elegant" ]), + Car.new("SUV", "red", [ "solid", "impressive" ]), + Car.new("Mustang", "red", [ "shiny", "impressive", "elegant" ]), + Car.new("Bullet-GT", "red", [ "shiny", "impressive", "fast", "elegant" ]), + Car.new("GTI", "blue", [ "average" ]), + Car.new("Deudeuch", "violet", [ "dirty", "slow", "only French will understand" ]) + ] + + # Equality is true if every property is identical. + def ==(other) + @name == other.name && @color == other.color && @keywords == other.keywords + end +end + +def ram_indexes(storage : DODB::Storage) + n = storage.new_RAM_index "name", &.name + c = storage.new_RAM_partition "color", &.color + k = storage.new_RAM_tags "keyword", &.keywords + return n, c, k +end + +def cached_indexes(storage : DODB::Storage) + n = storage.new_index "name", &.name + c = storage.new_partition "color", &.color + k = storage.new_tags "keyword", &.keywords + return n, c, k +end + +def uncached_indexes(storage : DODB::Storage) + n = storage.new_uncached_index "name", &.name + c = storage.new_uncached_partition "color", &.color + k = storage.new_uncached_tags "keyword", &.keywords + return n, c, k +end + +def add_cars(storage : DODB::Storage, nb_iterations : Int32, from = 0) + i = from + car1 = Car.new "Corvet", "red", [ "shiny", "impressive", "fast", "elegant" ] + car2 = Car.new "Bullet-GT", "blue", [ "shiny", "fast", "expensive" ] + car3 = Car.new "Deudeuche", "beige", [ "curvy", "sublime" ] + car4 = Car.new "Ford-5", "red", [ "unknown" ] + car5 = Car.new "C-MAX", "gray", [ "spacious", "affordable" ] + + while i < nb_iterations + car1.name = "Corvet-#{i}" + car2.name = "Bullet-GT-#{i}" + car3.name = "Deudeuche-#{i}" + car4.name = "Ford-5-#{i}" + car5.name = "C-MAX-#{i}" + + storage << car1 + storage << car2 + storage << car3 + storage << car4 + storage << car5 + i += 1 + #STDOUT.write "\radding value #{i}".to_slice + end + #puts "" +end diff --git a/spec/spec-database.cr b/spec/spec-database.cr new file mode 100644 index 0000000..6a78f8e --- /dev/null +++ b/spec/spec-database.cr @@ -0,0 +1,50 @@ +class DODB::SpecDataBase(V) < DODB::DataBase(V) + property storage_dir : String + def initialize(storage_ext = "", remove_previous_data = true) + @storage_dir = "test-spec-storage#{storage_ext}" + + if remove_previous_data + ::FileUtils.rm_rf storage_dir + end + + super storage_dir + end + + def rm_storage_dir + ::FileUtils.rm_rf @storage_dir + end +end + +class DODB::CachedSpecDataBase(V) < DODB::CachedDataBase(V) + property storage_dir : String + def initialize(storage_ext = "", remove_previous_data = true) + @storage_dir = "test-spec-storage-cached#{storage_ext}" + + if remove_previous_data + ::FileUtils.rm_rf storage_dir + end + + super storage_dir + end + + def rm_storage_dir + ::FileUtils.rm_rf @storage_dir + end +end + +class DODB::RAMOnlySpecDataBase(V) < DODB::RAMOnlyDataBase(V) + property storage_dir : String + def initialize(storage_ext = "", remove_previous_data = true) + @storage_dir = "test-spec-storage-ram#{storage_ext}" + + if remove_previous_data + ::FileUtils.rm_rf storage_dir + end + + super storage_dir + end + + def rm_storage_dir + ::FileUtils.rm_rf @storage_dir + end +end diff --git a/spec/test-data.cr b/spec/test-data.cr index 42da67e..2df42ed 100644 --- a/spec/test-data.cr +++ b/spec/test-data.cr @@ -85,24 +85,3 @@ class PrimitiveShip @@asakaze ] end - -class Car - include JSON::Serializable - - property name : String # unique to each instance (1-1 relations) - property color : String # a simple attribute (1-n relations) - property keywords : Array(String) # tags about a car, example: "shiny" (n-n relations) - - def_clone - - def initialize(@name, @color, @keywords) - end - class_getter cars = [ - Car.new("Corvet", "red", [ "shiny", "impressive", "fast", "elegant" ]), - Car.new("SUV", "red", [ "solid", "impressive" ]), - Car.new("Mustang", "red", [ "shiny", "impressive", "elegant" ]), - Car.new("Bullet-GT", "red", [ "shiny", "impressive", "fast", "elegant" ]), - Car.new("GTI", "blue", [ "average" ]), - Car.new("Deudeuch", "violet", [ "dirty", "slow", "only French will understand" ]) - ] -end diff --git a/spec/test.cr b/spec/test.cr index cb26ab6..25f265e 100644 --- a/spec/test.cr +++ b/spec/test.cr @@ -2,28 +2,17 @@ require "spec" require "file_utils" require "../src/dodb.cr" +require "./spec-database.cr" require "./test-data.cr" def fork_process(&) Process.new Crystal::System::Process.fork { yield } end -class DODB::SpecDataBase < DODB::DataBase(Ship) - def initialize(storage_ext = "", remove_previous_data = true) - storage_dir = "test-storage#{storage_ext}" - - if remove_previous_data - ::FileUtils.rm_rf storage_dir - end - - super storage_dir - end -end - describe "DODB::DataBase" do describe "basics" do it "store and get data" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new Ship.all_ships.each do |ship| db << ship @@ -33,7 +22,7 @@ describe "DODB::DataBase" do end it "rewrite already stored data" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new ship = Ship.all_ships[0] key = db << ship @@ -45,7 +34,7 @@ describe "DODB::DataBase" do end it "properly remove data" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new Ship.all_ships.each do |ship| db << ship @@ -66,19 +55,19 @@ describe "DODB::DataBase" do end it "preserves data on reopening" do - db1 = DODB::SpecDataBase.new + db1 = DODB::SpecDataBase(Ship).new db1 << Ship.kisaragi db1.to_a.size.should eq(1) - db2 = DODB::SpecDataBase.new remove_previous_data: false + db2 = DODB::SpecDataBase(Ship).new remove_previous_data: false db2 << Ship.mutsuki db1.to_a.size.should eq(2) end it "iterates in normal and reversed order" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new Ship.all_ships.each do |ship| db << ship @@ -98,7 +87,7 @@ describe "DODB::DataBase" do end it "respects the provided offsets if any" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new Ship.all_ships.each do |ship| db << ship @@ -116,7 +105,7 @@ describe "DODB::DataBase" do describe "indices" do it "do basic indexing" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_name = db.new_index "name", &.name @@ -130,7 +119,7 @@ describe "DODB::DataBase" do end it "raise on index overload" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_name = db.new_index "name", &.name @@ -144,7 +133,7 @@ describe "DODB::DataBase" do end it "properly deindex" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_name = db.new_index "name", &.name @@ -162,7 +151,7 @@ describe "DODB::DataBase" do end it "properly reindex" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_name = db.new_index "name", &.name @@ -180,7 +169,7 @@ describe "DODB::DataBase" do end it "properly updates" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_name = db.new_index "name", &.name @@ -202,7 +191,7 @@ describe "DODB::DataBase" do describe "partitions" do it "do basic partitioning" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_class = db.new_partition "class", &.klass @@ -230,7 +219,7 @@ describe "DODB::DataBase" do end it "removes select elements from partitions" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_class = db.new_partition "class", &.klass @@ -250,7 +239,7 @@ describe "DODB::DataBase" do describe "tags" do it "do basic tagging" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_tags = db.new_tags "tags", &.tags @@ -271,7 +260,7 @@ describe "DODB::DataBase" do end it "properly removes tags" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_tags = db.new_tags "tags", &.tags @@ -295,7 +284,7 @@ describe "DODB::DataBase" do end it "gets items that have multiple tags" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_tags = db.new_tags "tags", &.tags @@ -316,7 +305,7 @@ describe "DODB::DataBase" do describe "atomic operations" do it "safe_get and safe_get?" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_name = db.new_index "name", &.name @@ -338,7 +327,7 @@ describe "DODB::DataBase" do describe "tools" do it "rebuilds indexes" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_ships_by_name = db.new_index "name", &.name db_ships_by_class = db.new_partition "class", &.klass @@ -370,7 +359,7 @@ describe "DODB::DataBase" do # At this point, the “old” DB is filled. Now we need to convert # to the new DB. - new_db = DODB::SpecDataBase.new "-migration-target" + new_db = DODB::SpecDataBase(Ship).new "-migration-target" new_ships_by_name = new_db.new_index "name", &.name new_ships_by_class = new_db.new_partition "class", &.klass @@ -407,7 +396,7 @@ describe "DODB::DataBase" do entries_per_fork = 100 it "works for pushing values" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new processes = [] of Process @@ -427,7 +416,7 @@ describe "DODB::DataBase" do end it "works for updating values" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_entries_by_name = db.new_index "name", &.name # First pass, creating data. @@ -465,7 +454,7 @@ describe "DODB::DataBase" do end it "does parallel-safe updates" do - db = DODB::SpecDataBase.new + db = DODB::SpecDataBase(Ship).new db_entries_by_name = db.new_index "name", &.name # We’ll be storing an integer in the "klass" field, and incrementing