Skip to content
This repository has been archived by the owner on Aug 21, 2023. It is now read-only.

add shard.yml #6

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions shard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: mongo.cr
version: 0.1.0

authors:
- Kent Sibilev <[email protected]>

license: MIT
209 changes: 151 additions & 58 deletions spec/bson_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -122,55 +122,6 @@ describe BSON do
bson["ru"].should eq("привет")
end

it "should be able to append document" do
bson = BSON.new
bson["v"] = 1
bson.append_document("doc") do |child|
child["body"] = "document body"
end

doc = bson["doc"]
if doc.is_a?(BSON)
doc.has_key?("body").should be_true
doc["body"].should eq("document body")
else
fail "doc must be BSON object"
end
end

it "should invalidate child document after append" do
bson = BSON.new
bson["v"] = 1
child = nil
bson.append_document("doc") do |child|
child.not_nil!["body"] = "document body"
end
expect_raises do
child.not_nil!["v"] = 2
end
end

it "should be able to append an array" do
bson = BSON.new
bson["v"] = 1
bson.append_array("ary") do |child|
child << "a1"
child << "a2"
child << nil
child << 1
end

ary = bson["ary"]
if ary.is_a?(BSON)
ary.count.should eq(4)
ary["0"].should eq("a1")
ary["2"].should be_nil
ary["3"].should eq(1)
else
fail "ary must be BSON object"
end
end

it "should be able to append symbol" do
bson = BSON.new
bson["s"] = BSON::Symbol.new("symbol")
Expand Down Expand Up @@ -313,16 +264,22 @@ describe BSON do
end

it "should be able to decode bson" do
bson = BSON.new
bson["x"] = 42
bson.append_array("ary") do |child|
child << 1
child << 2
child << 3
end
bson.append_document("doc") do |child|
child["y"] = "text"
bson = BSON.build do |doc|
doc.field("x", 42)
doc.field("ary") do |appender|
appender.array do |array|
array << 1
array << 2
array << 3
end
end
doc.field("doc") do |appender|
appender.document do |doc|
doc.field("y", "text")
end
end
end

h = {"x" => 42, "ary" => [1,2,3], "doc" => {"y" => "text"}}
bson.decode.should eq(h)
end
Expand All @@ -335,4 +292,140 @@ describe BSON do
fail "expected BSON" unless ary.is_a?(BSON)
ary["0"].should eq(1)
end

context "build" do
it "yields a BSON::Builder" do
BSON.build do |builder|
builder.should be_a(BSON::Builder)
end
end

it "returns a bson" do
BSON.build {}.should be_a(BSON)
end

it "is able to add fields" do
bson = BSON.build do |doc|
doc.field("foo", "bar")
doc.field(:bar, "baz")
doc.field(1, "foobar")
end

bson["foo"].should eq("bar")
bson["bar"].should eq("baz")
bson["1"].should eq("foobar")
end

it "should be able to append document" do
bson = BSON.build do |doc|
doc.field("doc") do |appender|
appender.document do |child|
child.field("body", "document body")
end
end
end

doc = bson["doc"]
if doc.is_a?(BSON)
doc.has_key?("body").should be_true
doc["body"].should eq("document body")
else
fail "doc must be BSON object"
end
end

it "should invalidate child document after append" do
child_doc = nil
bson = BSON.build do |doc|
doc.field("doc") do |appender|
appender.document do |child|
child_doc = child.bson
child.field("body", "document body")
end
end
end

expect_raises do
child_doc.not_nil!["v"] = 2
end
end

it "should be able to append an array" do
bson = BSON.build do |doc|
doc.field("ary") do |appender|
appender.array do |array|
array << "a1"
array << "a2"
array << nil
array << 1
end
end
end

ary = bson["ary"]
if ary.is_a?(BSON)
ary.count.should eq(4)
ary["0"].should eq("a1")
ary["2"].should be_nil
ary["3"].should eq(1)
else
fail "ary must be BSON object"
end
end
end

context "from bson" do
it "creates an array from a bson array" do
bson = BSON.build_array do |doc|
doc << "foo"
doc << "bar"
doc << "baz"
end

Array(String).new(bson).should eq(%w(foo bar baz))
end

it "creates a hash from a bson document" do
bson = BSON.build do |doc|
doc.field(:foo, "bar")
doc.field(:bar, "baz")
end

Hash(String, String).new(bson).should eq({ "foo": "bar", "bar": "baz" })
end
end

context "mapping" do
it "produces a bson with all specified attributes" do
mapping = TestMapping.new("bar", OtherTestMapping.new("foo"), "one")
bson = mapping.to_bson
bson["foo"].should eq("bar")
bson["two"].should eq("one")
bson["baz"].should eq(0)
bar = bson["bar"]
if bar.is_a?(BSON)
bar["foobar"].should eq("foo - TEST")
else
fail "bar must be a BSON object"
end
end

it "maps all attributes from a bson" do
bson = BSON.build do |doc|
doc.field :foo, "bar"
doc.field :bar do |appender|
appender.document do |doc|
doc.field :foobar, "foo"
end
end
doc.field :two, "one"
end

mapping = TestMapping.new(bson)
mapping.foo.should eq("bar")
mapping.bar.foobar.should eq("foo")
mapping.one.should eq("one")
mapping.baz.should eq(0)
end
end
end
2 changes: 1 addition & 1 deletion spec/collection_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe Mongo::Collection do
doc["name"].should eq("Bob")
doc["age"].should eq(23)
cursor.more.should be_true
cursor.next.should be_nil
cursor.next.should be_a(Iterator::Stop)
cursor.more.should be_false
col.remove({"name" => "Bob"})
col.count.should eq(0)
Expand Down
2 changes: 1 addition & 1 deletion spec/database_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe Mongo::Database do

db.has_collection?("my_col").should be_true

col = db.find_collections.next.not_nil!
col = db.find_collections.next as BSON
col["name"].should eq("my_col")

db.collection_names.includes?("my_col").should be_true
Expand Down
31 changes: 31 additions & 0 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,35 @@ def with_collection
end
end

module TestConverter
extend self

def to_bson(bson_value, appender)
appender << "#{bson_value} - TEST"
end

def from_bson(bson_value)
bson_value.value as String
end
end

class OtherTestMapping
BSON.mapping({
foobar: { type: String, converter: TestConverter }
})

def initialize(@foobar : String)
end
end

class TestMapping
BSON.mapping({
foo: String,
bar: OtherTestMapping,
one: { type: String, key: :two },
baz: { type: Int32, default: 0 },
})

def initialize(@foo, @bar, @one, @baz = 0)
end
end
35 changes: 8 additions & 27 deletions src/bson.cr
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
require "./bson/lib_bson"
require "./bson/core_ext/*"
require "./bson/*"

class BSON
include Enumerable(Value)
include Comparable(BSON)

def self.build(&block : Builder -> _)
Builder.new.tap(&block).bson
end

def self.build_array(&block : ArrayBuilder -> _)
ArrayBuilder.new.tap(&block).bson
end

def initialize(@handle : LibBSON::BSON)
@valid = true
raise "invalid handle" unless @handle
Expand Down Expand Up @@ -206,32 +213,6 @@ class BSON
LibBSON.bson_append_regex(handle, key, key.bytesize, value.source, options)
end

def append_document(key)
unless LibBSON.bson_append_document_begin(handle, key, key.bytesize, out child_handle)
return false
end
child = BSON.new(pointerof(child_handle))
begin
yield child
ensure
LibBSON.bson_append_document_end(handle, child)
child.invalidate
end
end

def append_array(key)
unless LibBSON.bson_append_array_begin(handle, key, key.bytesize, out child_handle)
return false
end
child = BSON.new(pointerof(child_handle))
begin
yield ArrayAppender.new(child), child
ensure
LibBSON.bson_append_array_end(handle, child)
child.invalidate
end
end

def data
data = LibBSON.bson_get_data(handle)
Slice.new(data, handle.value.len.to_i32)
Expand Down
49 changes: 49 additions & 0 deletions src/bson/appender.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
class BSON
class Appender
getter? appended
def initialize(key, @bson)
@key = key.to_s
@appended = false
end

def document
raise "already appended a value" if appended?

unless LibBSON.bson_append_document_begin(@bson, @key, @key.bytesize, out child_handle)
return false
end
child = BSON.new(pointerof(child_handle))
begin
yield Builder.new(child)
ensure
LibBSON.bson_append_document_end(@bson, child)
child.invalidate
@appended = true
end
end

def array
raise "already appended a value" if appended?

unless LibBSON.bson_append_array_begin(@bson, @key, @key.bytesize, out child_handle)
return false
end

child = BSON.new(pointerof(child_handle))
begin
yield ArrayBuilder.new(child)
ensure
LibBSON.bson_append_array_end(@bson, child)
child.invalidate
@appended = true
end
end

def <<(value)
raise "already appended a value" if appended?
@bson[@key] = value
ensure
@appended = true
end
end
end
Loading