WIP: CBOR implementation.
parent
4792d8878f
commit
ffce08b36c
|
@ -8,4 +8,8 @@ authors:
|
||||||
description: |
|
description: |
|
||||||
Simple, embeddable Document-Oriented DataBase in Crystal.
|
Simple, embeddable Document-Oriented DataBase in Crystal.
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
cbor:
|
||||||
|
git: https://git.baguette.netlib.re/Baguette/crystal-cbor
|
||||||
|
|
||||||
license: MIT
|
license: MIT
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
require "uuid"
|
require "uuid"
|
||||||
require "json"
|
require "cbor"
|
||||||
|
|
||||||
# FIXME: Split the test data in separate files. We don’t care about those here.
|
# FIXME: Split the test data in separate files. We don’t care about those here.
|
||||||
|
|
||||||
class Ship
|
class Ship
|
||||||
include JSON::Serializable
|
include CBOR::Serializable
|
||||||
|
|
||||||
def_clone
|
def_clone
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ end
|
||||||
# This will be used for migration testing, but basically it’s a variant of
|
# This will be used for migration testing, but basically it’s a variant of
|
||||||
# the class above, a few extra fields, a few missing ones.
|
# the class above, a few extra fields, a few missing ones.
|
||||||
class PrimitiveShip
|
class PrimitiveShip
|
||||||
include JSON::Serializable
|
include CBOR::Serializable
|
||||||
|
|
||||||
property id : String
|
property id : String
|
||||||
property name : String
|
property name : String
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require "file_utils"
|
require "file_utils"
|
||||||
require "json"
|
require "cbor"
|
||||||
|
|
||||||
class Hash(K,V)
|
class Hash(K,V)
|
||||||
def reverse
|
def reverse
|
||||||
|
@ -63,7 +63,7 @@ class DODB::CachedDataBase(V) < DODB::Storage(V)
|
||||||
|
|
||||||
# Avoids corruption in case the application crashes while writing.
|
# Avoids corruption in case the application crashes while writing.
|
||||||
file_path(index).tap do |path|
|
file_path(index).tap do |path|
|
||||||
::File.write "#{path}.new", value.to_json
|
::File.write "#{path}.new", value.to_cbor
|
||||||
::FileUtils.mv "#{path}.new", path
|
::FileUtils.mv "#{path}.new", path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
12
src/dodb.cr
12
src/dodb.cr
|
@ -1,8 +1,12 @@
|
||||||
require "file_utils"
|
require "file_utils"
|
||||||
require "json"
|
require "cbor"
|
||||||
|
|
||||||
require "./dodb/*"
|
require "./dodb/*"
|
||||||
|
|
||||||
|
module DODB
|
||||||
|
class_property file_extension = ".cbor"
|
||||||
|
end
|
||||||
|
|
||||||
abstract class DODB::Storage(V)
|
abstract class DODB::Storage(V)
|
||||||
property directory_name : String
|
property directory_name : String
|
||||||
|
|
||||||
|
@ -200,7 +204,7 @@ abstract class DODB::Storage(V)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def file_path(key : Int32)
|
private def file_path(key : Int32)
|
||||||
"#{data_path}/%010i.json" % key
|
"#{data_path}/%010i#{DODB.file_extension}" % key
|
||||||
end
|
end
|
||||||
|
|
||||||
private def locks_directory : String
|
private def locks_directory : String
|
||||||
|
@ -216,7 +220,7 @@ abstract class DODB::Storage(V)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def read(file_path : String)
|
private def read(file_path : String)
|
||||||
V.from_json ::File.read file_path
|
V.from_cbor ::File.read(file_path).to_slice
|
||||||
end
|
end
|
||||||
|
|
||||||
private def remove_data!
|
private def remove_data!
|
||||||
|
@ -294,7 +298,7 @@ class DODB::DataBase(V) < DODB::Storage(V)
|
||||||
|
|
||||||
# Avoids corruption in case the application crashes while writing.
|
# Avoids corruption in case the application crashes while writing.
|
||||||
file_path(index).tap do |path|
|
file_path(index).tap do |path|
|
||||||
::File.write "#{path}.new", value.to_json
|
::File.write "#{path}.new", value.to_cbor
|
||||||
::FileUtils.mv "#{path}.new", path
|
::FileUtils.mv "#{path}.new", path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require "file_utils"
|
require "file_utils"
|
||||||
require "json"
|
require "cbor"
|
||||||
|
|
||||||
require "./indexer.cr"
|
require "./indexer.cr"
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class DODB::DirectedGraph(V) < DODB::Indexer(V)
|
||||||
return r_value unless Dir.exists? incoming_links_directory
|
return r_value unless Dir.exists? incoming_links_directory
|
||||||
|
|
||||||
Dir.each_child incoming_links_directory do |child|
|
Dir.each_child incoming_links_directory do |child|
|
||||||
r_value << V.from_json ::File.read "#{incoming_links_directory}/#{child}"
|
r_value << V.from_cbor ::File.read("#{incoming_links_directory}/#{child}").to_slice
|
||||||
end
|
end
|
||||||
|
|
||||||
r_value
|
r_value
|
||||||
|
@ -91,7 +91,7 @@ class DODB::DirectedGraph(V) < DODB::Indexer(V)
|
||||||
return r_value unless Dir.exists? incoming_links_directory
|
return r_value unless Dir.exists? incoming_links_directory
|
||||||
|
|
||||||
Dir.each_child incoming_links_directory do |child|
|
Dir.each_child incoming_links_directory do |child|
|
||||||
r_value << child.sub /.json$/, ""
|
r_value << child.sub /#{DODB.file_extension}$/, ""
|
||||||
end
|
end
|
||||||
|
|
||||||
r_value
|
r_value
|
||||||
|
@ -107,7 +107,7 @@ class DODB::DirectedGraph(V) < DODB::Indexer(V)
|
||||||
return r_value unless Dir.exists? outgoing_links_directory
|
return r_value unless Dir.exists? outgoing_links_directory
|
||||||
|
|
||||||
Dir.each_child outgoing_links_directory do |child|
|
Dir.each_child outgoing_links_directory do |child|
|
||||||
r_value << V.from_json ::File.read "#{outgoing_links_directory}/#{child}"
|
r_value << V.from_cbor ::File.read("#{outgoing_links_directory}/#{child}").to_slice
|
||||||
end
|
end
|
||||||
|
|
||||||
r_value
|
r_value
|
||||||
|
@ -120,7 +120,7 @@ class DODB::DirectedGraph(V) < DODB::Indexer(V)
|
||||||
return r_value unless Dir.exists? outgoing_links_directory
|
return r_value unless Dir.exists? outgoing_links_directory
|
||||||
|
|
||||||
Dir.each_child outgoing_links_directory do |child|
|
Dir.each_child outgoing_links_directory do |child|
|
||||||
r_value << child.sub /.json$/, ""
|
r_value << child.sub /#{DODB.file_extension}$/, ""
|
||||||
end
|
end
|
||||||
|
|
||||||
r_value
|
r_value
|
||||||
|
@ -132,7 +132,7 @@ class DODB::DirectedGraph(V) < DODB::Indexer(V)
|
||||||
|
|
||||||
private def get_key(path : String) : Int32
|
private def get_key(path : String) : Int32
|
||||||
::File.readlink(path)
|
::File.readlink(path)
|
||||||
.sub(/\.json$/, "")
|
.sub(/#{DODB.file_extension}$/, "")
|
||||||
.sub(/^.*\//, "")
|
.sub(/^.*\//, "")
|
||||||
.to_i
|
.to_i
|
||||||
end
|
end
|
||||||
|
@ -142,7 +142,7 @@ class DODB::DirectedGraph(V) < DODB::Indexer(V)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def get_node_symlink(node : String, key : String)
|
private def get_node_symlink(node : String, key : String)
|
||||||
"#{indexing_directory node}/#{key}.json"
|
"#{indexing_directory node}/#{key}#{DODB.file_extension}"
|
||||||
end
|
end
|
||||||
|
|
||||||
private def get_outgoing_links_directory(node)
|
private def get_outgoing_links_directory(node)
|
||||||
|
@ -162,13 +162,13 @@ class DODB::DirectedGraph(V) < DODB::Indexer(V)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def get_data_symlink(key : String)
|
private def get_data_symlink(key : String)
|
||||||
"../../../../data/#{key}.json"
|
"../../../../data/#{key}#{DODB.file_extension}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Roughly matches Index#file_path_index, but works if @storage_root
|
# Roughly matches Index#file_path_index, but works if @storage_root
|
||||||
# is an absolute path as well.
|
# is an absolute path as well.
|
||||||
private def get_cross_index_data_symlink(node : String)
|
private def get_cross_index_data_symlink(node : String)
|
||||||
"../../../../indices/by_#{@index.name}/#{node}.json"
|
"../../../../indices/by_#{@index.name}/#{node}#{DODB.file_extension}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require "file_utils"
|
require "file_utils"
|
||||||
require "json"
|
require "cbor"
|
||||||
|
|
||||||
require "./exceptions.cr"
|
require "./exceptions.cr"
|
||||||
require "./indexer.cr"
|
require "./indexer.cr"
|
||||||
|
@ -63,7 +63,7 @@ class DODB::Index(V) < DODB::Indexer(V)
|
||||||
|
|
||||||
raise MissingEntry.new(@name, index) unless ::File.exists? file_path
|
raise MissingEntry.new(@name, index) unless ::File.exists? file_path
|
||||||
|
|
||||||
V.from_json ::File.read file_path
|
V.from_cbor ::File.read(file_path).to_slice
|
||||||
end
|
end
|
||||||
|
|
||||||
def get?(index : String) : V?
|
def get?(index : String) : V?
|
||||||
|
@ -96,7 +96,7 @@ class DODB::Index(V) < DODB::Indexer(V)
|
||||||
raise MissingEntry.new(@name, index) unless ::File.exists? file_path
|
raise MissingEntry.new(@name, index) unless ::File.exists? file_path
|
||||||
|
|
||||||
::File.readlink(file_path)
|
::File.readlink(file_path)
|
||||||
.sub(/\.json$/, "")
|
.sub(/#{DODB.file_extension}$/, "")
|
||||||
.sub(/^.*\//, "")
|
.sub(/^.*\//, "")
|
||||||
.to_i
|
.to_i
|
||||||
end
|
end
|
||||||
|
@ -142,11 +142,11 @@ class DODB::Index(V) < DODB::Indexer(V)
|
||||||
|
|
||||||
# FIXME: Now that it’s being used outside of this class, name it properly.
|
# FIXME: Now that it’s being used outside of this class, name it properly.
|
||||||
def file_path_index(index_key : String)
|
def file_path_index(index_key : String)
|
||||||
"#{indexing_directory}/#{index_key}.json"
|
"#{indexing_directory}/#{index_key}#{DODB.file_extension}"
|
||||||
end
|
end
|
||||||
|
|
||||||
private def get_data_symlink_index(key : String)
|
private def get_data_symlink_index(key : String)
|
||||||
"../../data/#{key}.json"
|
"../../data/#{key}#{DODB.file_extension}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require "file_utils"
|
require "file_utils"
|
||||||
require "json"
|
require "cbor"
|
||||||
|
|
||||||
require "./indexer.cr"
|
require "./indexer.cr"
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ class DODB::Partition(V) < DODB::Indexer(V)
|
||||||
return r_value unless Dir.exists? partition_directory
|
return r_value unless Dir.exists? partition_directory
|
||||||
|
|
||||||
Dir.each_child partition_directory do |child|
|
Dir.each_child partition_directory do |child|
|
||||||
r_value << V.from_json ::File.read "#{partition_directory}/#{child}"
|
r_value << V.from_cbor ::File.read("#{partition_directory}/#{child}").to_slice
|
||||||
end
|
end
|
||||||
|
|
||||||
r_value
|
r_value
|
||||||
|
@ -64,7 +64,7 @@ class DODB::Partition(V) < DODB::Indexer(V)
|
||||||
|
|
||||||
Dir.each_child partition_directory do |child|
|
Dir.each_child partition_directory do |child|
|
||||||
path = "#{partition_directory}/#{child}"
|
path = "#{partition_directory}/#{child}"
|
||||||
item = V.from_json ::File.read path
|
item = V.from_cbor ::File.read(path).to_slice
|
||||||
|
|
||||||
if yield item
|
if yield item
|
||||||
key = get_key path
|
key = get_key path
|
||||||
|
@ -80,7 +80,7 @@ class DODB::Partition(V) < DODB::Indexer(V)
|
||||||
|
|
||||||
private def get_key(path : String) : Int32
|
private def get_key(path : String) : Int32
|
||||||
::File.readlink(path)
|
::File.readlink(path)
|
||||||
.sub(/\.json$/, "")
|
.sub(/#{DODB.file_extension}$/, "")
|
||||||
.sub(/^.*\//, "")
|
.sub(/^.*\//, "")
|
||||||
.to_i
|
.to_i
|
||||||
end
|
end
|
||||||
|
@ -90,11 +90,11 @@ class DODB::Partition(V) < DODB::Indexer(V)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def get_partition_symlink(partition : String, key : String)
|
private def get_partition_symlink(partition : String, key : String)
|
||||||
"#{indexing_directory partition}/#{key}.json"
|
"#{indexing_directory partition}/#{key}#{DODB.file_extension}"
|
||||||
end
|
end
|
||||||
|
|
||||||
private def get_data_symlink(key : String)
|
private def get_data_symlink(key : String)
|
||||||
"../../../data/#{key}.json"
|
"../../../data/#{key}#{DODB.file_extension}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require "file_utils"
|
require "file_utils"
|
||||||
require "json"
|
require "cbor"
|
||||||
|
|
||||||
class DODB::Tags(V) < DODB::Indexer(V)
|
class DODB::Tags(V) < DODB::Indexer(V)
|
||||||
property name : String
|
property name : String
|
||||||
|
@ -76,8 +76,8 @@ class DODB::Tags(V) < DODB::Indexer(V)
|
||||||
|
|
||||||
Dir.each_child partition_directory do |child|
|
Dir.each_child partition_directory do |child|
|
||||||
r_value << {
|
r_value << {
|
||||||
V.from_json(::File.read("#{partition_directory}/#{child}")),
|
V.from_cbor(::File.read("#{partition_directory}/#{child}").to_slice),
|
||||||
File.basename(child).gsub(/\.json$/, "").to_i
|
File.basename(child).gsub(/#{DODB.file_extension}$/, "").to_i
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -104,10 +104,10 @@ class DODB::Tags(V) < DODB::Indexer(V)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def get_tagged_entry_path(key : String, indices : Array(String))
|
private def get_tagged_entry_path(key : String, indices : Array(String))
|
||||||
"#{indexing_directory}#{indices.map { |i| "/other-tags/#{i}" }.join}/data/#{key}.json"
|
"#{indexing_directory}#{indices.map { |i| "/other-tags/#{i}" }.join}/data/#{key}#{DODB.file_extension}"
|
||||||
end
|
end
|
||||||
private def get_data_symlink(key : String, indices : Array(String))
|
private def get_data_symlink(key : String, indices : Array(String))
|
||||||
"../../../#{indices.map { "../../" }.join}/data/#{key}.json"
|
"../../../#{indices.map { "../../" }.join}/data/#{key}#{DODB.file_extension}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue