diametric 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +22 -0
- data/Gemfile +14 -0
- data/Guardfile +8 -0
- data/Jarfile +6 -0
- data/Jarfile.lock +126 -0
- data/LICENSE.txt +22 -0
- data/README.md +215 -0
- data/Rakefile +17 -0
- data/TODO.org +12 -0
- data/diametric.gemspec +31 -0
- data/lib/diametric.rb +9 -0
- data/lib/diametric/entity.rb +339 -0
- data/lib/diametric/persistence/common.rb +29 -0
- data/lib/diametric/persistence/peer.rb +107 -0
- data/lib/diametric/persistence/rest.rb +88 -0
- data/lib/diametric/query.rb +157 -0
- data/lib/diametric/version.rb +3 -0
- data/lib/jrclj.rb +63 -0
- data/spec/diametric/entity_spec.rb +128 -0
- data/spec/diametric/persistence/peer_spec.rb +36 -0
- data/spec/diametric/persistence/rest_spec.rb +30 -0
- data/spec/diametric/query_spec.rb +63 -0
- data/spec/integration_spec.rb +67 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/support/persistence_examples.rb +68 -0
- metadata +164 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'diametric/persistence/rest'
|
3
|
+
|
4
|
+
describe Diametric::Persistence::REST, :integration do
|
5
|
+
class Mouse
|
6
|
+
include Diametric::Entity
|
7
|
+
include Diametric::Persistence::REST
|
8
|
+
|
9
|
+
attribute :name, String, :index => true
|
10
|
+
attribute :age, Integer
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:db_uri) { ENV['DATOMIC_URI'] || 'http://localhost:9000' }
|
14
|
+
let(:storage) { ENV['DATOMIC_STORAGE'] || 'test' }
|
15
|
+
let(:dbname) { ENV['DATOMIC_NAME'] || "test-#{Time.now.to_i}" }
|
16
|
+
|
17
|
+
it "can connect to a Datomic database" do
|
18
|
+
subject.connect(db_uri, storage, dbname)
|
19
|
+
subject.connection.should be_a(Datomic::Client)
|
20
|
+
end
|
21
|
+
|
22
|
+
it_behaves_like "persistence API" do
|
23
|
+
let(:model_class) { Mouse }
|
24
|
+
|
25
|
+
before(:all) do
|
26
|
+
subject.connect(db_uri, storage, dbname)
|
27
|
+
Diametric::Persistence::REST.create_schemas
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Diametric::Query do
|
4
|
+
let(:query) { Diametric::Query.new(Goat) }
|
5
|
+
|
6
|
+
describe "#where" do
|
7
|
+
it "is non-destructive" do
|
8
|
+
query.where(:age => 2)
|
9
|
+
query.conditions.should be_empty
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#filter" do
|
14
|
+
it "is non-destructive" do
|
15
|
+
query.filter(:<, :age, 2)
|
16
|
+
query.filters.should be_empty
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
describe "#data" do
|
22
|
+
it "should generate a query given no conditions or filters" do
|
23
|
+
query.data.should == [
|
24
|
+
[
|
25
|
+
:find, ~"?e", ~"?name", ~"?birthday",
|
26
|
+
:in, ~"\$",
|
27
|
+
:where,
|
28
|
+
[~"?e", :"goat/name", ~"?name"],
|
29
|
+
[~"?e", :"goat/birthday", ~"?birthday"]
|
30
|
+
],
|
31
|
+
[]
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should generate a query given a condition" do
|
36
|
+
query.where(:name => "Beans").data.should == [
|
37
|
+
[
|
38
|
+
:find, ~"?e", ~"?name", ~"?birthday",
|
39
|
+
:in, ~"\$", ~"?name",
|
40
|
+
:where,
|
41
|
+
[~"?e", :"goat/name", ~"?name"],
|
42
|
+
[~"?e", :"goat/birthday", ~"?birthday"]
|
43
|
+
],
|
44
|
+
["Beans"]
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should generate a query given multiple conditions" do
|
49
|
+
bday = DateTime.parse("2003-09-04 11:30 AM")
|
50
|
+
|
51
|
+
query.where(:name => "Beans", :birthday => bday).data.should == [
|
52
|
+
[
|
53
|
+
:find, ~"?e", ~"?name", ~"?birthday",
|
54
|
+
:in, ~"\$", ~"?name", ~"?birthday",
|
55
|
+
:where,
|
56
|
+
[~"?e", :"goat/name", ~"?name"],
|
57
|
+
[~"?e", :"goat/birthday", ~"?birthday"]
|
58
|
+
],
|
59
|
+
["Beans", bday]
|
60
|
+
]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'datomic/client'
|
3
|
+
|
4
|
+
# Datomic's `rest` needs to run for these tests to pass:
|
5
|
+
# bin/rest 9000 test datomic:mem://
|
6
|
+
|
7
|
+
describe Diametric::Entity, :integration => true do
|
8
|
+
before(:all) do
|
9
|
+
@datomic_uri = ENV['DATOMIC_URI'] || 'http://localhost:9000'
|
10
|
+
@storage = ENV['DATOMIC_STORAGE'] || 'test'
|
11
|
+
@dbname = ENV['DATOMIC_NAME'] || "test-#{Time.now.to_i}"
|
12
|
+
@client = Datomic::Client.new @datomic_uri, @storage
|
13
|
+
@client.create_database(@dbname)
|
14
|
+
sleep 0.5
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can load the schema" do
|
18
|
+
resp = @client.transact(@dbname, Person.schema)
|
19
|
+
resp.code.should == 201
|
20
|
+
resp.data.should be_a(Hash)
|
21
|
+
resp.data.keys.sort.should == [:"db-after", :"db-before", :tempids, :"tx-data"]
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "with a schema" do
|
25
|
+
before(:all) do
|
26
|
+
@client.transact(@dbname, Person.schema)
|
27
|
+
@client.transact(@dbname, Goat.schema)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can transact an entity" do
|
31
|
+
birthday = DateTime.parse("1976-09-04")
|
32
|
+
goat = Goat.new(:name => "Beans", :birthday => birthday)
|
33
|
+
resp = @client.transact(@dbname, goat.tx_data)
|
34
|
+
resp.code.should == 201
|
35
|
+
resp.data.should be_a(Hash)
|
36
|
+
resp.data.keys.sort.should == [:"db-after", :"db-before", :tempids, :"tx-data"]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "with an entity" do
|
41
|
+
before(:all) do
|
42
|
+
goat = Goat.new(:name => "Josef", :birthday => DateTime.parse("1976-09-04"))
|
43
|
+
@client.transact(@dbname, goat.tx_data)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "can query for that entity" do
|
47
|
+
query, args = Diametric::Query.new(Goat).where(:name => "Josef").data
|
48
|
+
args = args.unshift({:"db/alias" => "#{@storage}/#{@dbname}"})
|
49
|
+
resp = @client.query(query, args)
|
50
|
+
resp.code.should == 200
|
51
|
+
resp.data.should be_a(Array)
|
52
|
+
resp.data.count.should == 1
|
53
|
+
resp.data.first.count.should == 3
|
54
|
+
end
|
55
|
+
|
56
|
+
it "can rehydrate an entity from a query" do
|
57
|
+
query, args = Diametric::Query.new(Goat).where(:name => "Josef").data
|
58
|
+
args = args.unshift({:"db/alias" => "#{@storage}/#{@dbname}"})
|
59
|
+
resp = @client.query(query, args)
|
60
|
+
resp.code.should == 200
|
61
|
+
|
62
|
+
goats = resp.data.map { |data| Goat.from_query(data) }
|
63
|
+
goats.first.name.should == "Josef"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'pry'
|
3
|
+
require 'diametric'
|
4
|
+
Dir["./spec/support/**/*.rb"].each {|f| require f}
|
5
|
+
|
6
|
+
RSpec.configure do |c|
|
7
|
+
# c.fail_fast = true
|
8
|
+
|
9
|
+
c.filter_run_excluding :integration => true unless ENV['INTEGRATION']
|
10
|
+
c.filter_run_excluding :jruby => true unless RUBY_ENGINE == "jruby"
|
11
|
+
|
12
|
+
c.filter_run_including :focused => true
|
13
|
+
c.alias_example_to :fit, :focused => true
|
14
|
+
|
15
|
+
c.run_all_when_everything_filtered = true
|
16
|
+
c.treat_symbols_as_metadata_keys_with_true_values = true
|
17
|
+
end
|
18
|
+
|
19
|
+
shared_examples "ActiveModel" do |model|
|
20
|
+
require 'test/unit/assertions'
|
21
|
+
require 'active_model/lint'
|
22
|
+
include Test::Unit::Assertions
|
23
|
+
include ActiveModel::Lint::Tests
|
24
|
+
|
25
|
+
active_model_lints = ActiveModel::Lint::Tests.public_instance_methods.map(&:to_s).grep(/^test/)
|
26
|
+
|
27
|
+
let(:model) { subject }
|
28
|
+
|
29
|
+
active_model_lints.each do |test_name|
|
30
|
+
it "#{test_name.sub(/^test_/, '')}" do
|
31
|
+
send(test_name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Person
|
37
|
+
include Diametric::Entity
|
38
|
+
|
39
|
+
attribute :name, String, :index => true
|
40
|
+
attribute :email, String, :cardinality => :many
|
41
|
+
attribute :birthday, DateTime
|
42
|
+
attribute :awesome, :boolean, :doc => "Is this person awesome?"
|
43
|
+
attribute :ssn, String, :unique => :value
|
44
|
+
attribute :secret_name, String, :unique => :identity
|
45
|
+
attribute :bio, String, :fulltext => true
|
46
|
+
end
|
47
|
+
|
48
|
+
class Goat
|
49
|
+
include Diametric::Entity
|
50
|
+
|
51
|
+
attribute :name, String
|
52
|
+
attribute :birthday, DateTime
|
53
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
shared_examples "persistence API" do
|
2
|
+
describe "an instance" do
|
3
|
+
let(:model) { model_class.new }
|
4
|
+
|
5
|
+
it "can save" do
|
6
|
+
# TODO deal correctly with nil values
|
7
|
+
model.name = "Wilbur"
|
8
|
+
model.age = 2
|
9
|
+
model.save.should be_true
|
10
|
+
model.should be_persisted
|
11
|
+
end
|
12
|
+
|
13
|
+
it "does not transact if nothing is changed" do
|
14
|
+
model = model_class.new
|
15
|
+
model.should_not be_changed
|
16
|
+
model.save.should be_true
|
17
|
+
model.should_not be_persisted
|
18
|
+
end
|
19
|
+
|
20
|
+
it "does not transact if invalid" do
|
21
|
+
model.stub(:valid? => false)
|
22
|
+
model.save.should be_false
|
23
|
+
end
|
24
|
+
|
25
|
+
context "that is saved in Datomic" do
|
26
|
+
before(:each) do
|
27
|
+
model.name = "Wilbur"
|
28
|
+
model.age = 2
|
29
|
+
model.save
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can find it by dbid" do
|
33
|
+
model2 = model_class.get(model.dbid)
|
34
|
+
model2.should_not be_nil
|
35
|
+
model2.name.should == model.name
|
36
|
+
model2.should == model
|
37
|
+
end
|
38
|
+
|
39
|
+
it "can save it back to Datomic with changes" do
|
40
|
+
model.name = "Mr. Wilbur"
|
41
|
+
model.save.should be_true
|
42
|
+
|
43
|
+
model2 = model_class.get(model.dbid)
|
44
|
+
model2.name.should == "Mr. Wilbur"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "can find it by attribute" do
|
48
|
+
model2 = model_class.first(:name => "Wilbur")
|
49
|
+
model2.should_not be_nil
|
50
|
+
model2.dbid.should == model.dbid
|
51
|
+
model2.should == model
|
52
|
+
end
|
53
|
+
|
54
|
+
it "can find all matching conditions" do
|
55
|
+
mice = model_class.where(:name => "Wilbur").where(:age => 2).all
|
56
|
+
mice.should == [model]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "can filter entities" do
|
60
|
+
mice = model_class.filter(:<, :age, 3).all
|
61
|
+
mice.should == [model]
|
62
|
+
|
63
|
+
mice = model_class.filter(:>, :age, 3).all
|
64
|
+
mice.should == []
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
metadata
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: diametric
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Clinton N. Dreisbach
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: edn
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activesupport
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 3.0.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.0.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: activemodel
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 3.0.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.0.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: datomic-client
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.4.1
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.4.1
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: lock_jar
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.7.2
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 0.7.2
|
94
|
+
description: ! 'Diametric is a library for building schemas, queries, and transactions
|
95
|
+
|
96
|
+
for Datomic from Ruby objects. It is also used to map Ruby objects
|
97
|
+
|
98
|
+
as entities into a Datomic database.
|
99
|
+
|
100
|
+
'
|
101
|
+
email:
|
102
|
+
- crnixon@gmail.com
|
103
|
+
executables: []
|
104
|
+
extensions:
|
105
|
+
- Rakefile
|
106
|
+
extra_rdoc_files: []
|
107
|
+
files:
|
108
|
+
- .gitignore
|
109
|
+
- Gemfile
|
110
|
+
- Guardfile
|
111
|
+
- Jarfile
|
112
|
+
- Jarfile.lock
|
113
|
+
- LICENSE.txt
|
114
|
+
- README.md
|
115
|
+
- Rakefile
|
116
|
+
- TODO.org
|
117
|
+
- diametric.gemspec
|
118
|
+
- lib/diametric.rb
|
119
|
+
- lib/diametric/entity.rb
|
120
|
+
- lib/diametric/persistence/common.rb
|
121
|
+
- lib/diametric/persistence/peer.rb
|
122
|
+
- lib/diametric/persistence/rest.rb
|
123
|
+
- lib/diametric/query.rb
|
124
|
+
- lib/diametric/version.rb
|
125
|
+
- lib/jrclj.rb
|
126
|
+
- spec/diametric/entity_spec.rb
|
127
|
+
- spec/diametric/persistence/peer_spec.rb
|
128
|
+
- spec/diametric/persistence/rest_spec.rb
|
129
|
+
- spec/diametric/query_spec.rb
|
130
|
+
- spec/integration_spec.rb
|
131
|
+
- spec/spec_helper.rb
|
132
|
+
- spec/support/persistence_examples.rb
|
133
|
+
homepage: https://github.com/crnixon/diametric
|
134
|
+
licenses: []
|
135
|
+
post_install_message:
|
136
|
+
rdoc_options: []
|
137
|
+
require_paths:
|
138
|
+
- lib
|
139
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ! '>='
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
147
|
+
requirements:
|
148
|
+
- - ! '>='
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 1.8.23
|
154
|
+
signing_key:
|
155
|
+
specification_version: 3
|
156
|
+
summary: ActiveModel for Datomic
|
157
|
+
test_files:
|
158
|
+
- spec/diametric/entity_spec.rb
|
159
|
+
- spec/diametric/persistence/peer_spec.rb
|
160
|
+
- spec/diametric/persistence/rest_spec.rb
|
161
|
+
- spec/diametric/query_spec.rb
|
162
|
+
- spec/integration_spec.rb
|
163
|
+
- spec/spec_helper.rb
|
164
|
+
- spec/support/persistence_examples.rb
|