diametric 0.1.2-java → 0.1.3-java
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.
- checksums.yaml +4 -4
- data/Gemfile +3 -3
- data/Jarfile +13 -6
- data/LICENSE.txt +2 -2
- data/README.md +57 -26
- data/Rakefile +1 -0
- data/bin/datomic-rest +1 -1
- data/bin/download-datomic +1 -1
- data/datomic_version.yml +2 -2
- data/diametric-java.gemspec +11 -10
- data/ext/diametric/DiametricCollection.java +45 -38
- data/ext/diametric/DiametricConnection.java +16 -15
- data/ext/diametric/DiametricDatabase.java +9 -8
- data/ext/diametric/DiametricEntity.java +104 -21
- data/ext/diametric/DiametricObject.java +12 -1
- data/ext/diametric/DiametricPeer.java +52 -31
- data/ext/diametric/DiametricService.java +2 -0
- data/ext/diametric/DiametricSet.java +11 -4
- data/ext/diametric/DiametricUUID.java +8 -1
- data/ext/diametric/DiametricUtils.java +90 -62
- data/lib/diametric.rb +1 -0
- data/lib/diametric/associations/collection.rb +103 -0
- data/lib/diametric/entity.rb +166 -103
- data/lib/diametric/persistence/common.rb +0 -44
- data/lib/diametric/persistence/peer.rb +53 -2
- data/lib/diametric/persistence/rest.rb +27 -1
- data/lib/diametric/query.rb +49 -31
- data/lib/diametric/rest_service.rb +8 -9
- data/lib/diametric/service_base.rb +7 -7
- data/lib/diametric/transactor.rb +6 -5
- data/lib/diametric/version.rb +1 -1
- data/lib/diametric_service.jar +0 -0
- data/spec/config/free-transactor-template.properties +6 -6
- data/spec/developer_query_spec.rb +17 -6
- data/spec/diametric/entity_spec.rb +62 -139
- data/spec/diametric/peer_api_spec.rb +23 -23
- data/spec/diametric/persistence/peer_spec.rb +73 -11
- data/spec/diametric/persistence/rest_spec.rb +108 -16
- data/spec/diametric/query_spec.rb +3 -3
- data/spec/diametric/rest_service_spec.rb +4 -4
- data/spec/diametric/schema_spec.rb +526 -0
- data/spec/diametric/transactor_spec.rb +5 -6
- data/spec/integration_spec.rb +7 -7
- data/spec/peer_integration_spec.rb +25 -1
- data/spec/peer_seattle_spec.rb +1 -2
- data/spec/spec_helper.rb +31 -4
- data/spec/support/cardinarity_many_example.rb +37 -0
- data/spec/support/entities.rb +127 -0
- data/spec/support/has_a_example.rb +31 -0
- data/spec/support/has_many_example.rb +79 -0
- data/spec/support/persistence_examples.rb +13 -5
- data/spec/support/various_types_examples.rb +163 -0
- data/spec/test_version_file.yml +2 -2
- metadata +147 -75
@@ -2,7 +2,6 @@ module Diametric
|
|
2
2
|
module Persistence
|
3
3
|
module Common
|
4
4
|
def self.included(base)
|
5
|
-
base.send(:extend, ClassMethods)
|
6
5
|
base.send(:include, InstanceMethods)
|
7
6
|
end
|
8
7
|
|
@@ -34,49 +33,6 @@ module Diametric
|
|
34
33
|
return true
|
35
34
|
end
|
36
35
|
end
|
37
|
-
|
38
|
-
module ClassMethods
|
39
|
-
def create_schema(connection=nil)
|
40
|
-
if self.instance_variable_get("@peer")
|
41
|
-
connection ||= Diametric::Persistence::Peer.connect
|
42
|
-
connection.transact(schema)
|
43
|
-
else
|
44
|
-
transact(schema)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def all(connection=nil, resolve=true)
|
49
|
-
if self.instance_variable_get("@peer")
|
50
|
-
connection ||= Diametric::Persistence::Peer.connect
|
51
|
-
end
|
52
|
-
Diametric::Query.new(self, connection, resolve).all
|
53
|
-
end
|
54
|
-
|
55
|
-
def first(conditions = {}, connection=nil, resolve=true)
|
56
|
-
if self.instance_variable_get("@peer")
|
57
|
-
connection ||= Diametric::Persistence::Peer.connect
|
58
|
-
end
|
59
|
-
where(conditions, connection, resolve).first
|
60
|
-
end
|
61
|
-
|
62
|
-
def where(conditions = {}, connection=nil, resolve=true)
|
63
|
-
if self.instance_variable_get("@peer")
|
64
|
-
connection ||= Diametric::Persistence::Peer.connect
|
65
|
-
end
|
66
|
-
query = Diametric::Query.new(self, connection, resolve)
|
67
|
-
query.where(conditions)
|
68
|
-
end
|
69
|
-
|
70
|
-
def filter(*filter)
|
71
|
-
if self.instance_variable_get("@peer")
|
72
|
-
connection = Diametric::Persistence::Peer.connect
|
73
|
-
else
|
74
|
-
connection = nil
|
75
|
-
end
|
76
|
-
query = Diametric::Query.new(self, connection, true)
|
77
|
-
query.filter(*filter)
|
78
|
-
end
|
79
|
-
end
|
80
36
|
end
|
81
37
|
end
|
82
38
|
end
|
@@ -3,7 +3,6 @@ require 'diametric/persistence/common'
|
|
3
3
|
module Diametric
|
4
4
|
module Persistence
|
5
5
|
module Peer
|
6
|
-
|
7
6
|
def save(connection=nil)
|
8
7
|
return false unless valid?
|
9
8
|
return true unless changed?
|
@@ -12,8 +11,16 @@ module Diametric
|
|
12
11
|
parsed_data = []
|
13
12
|
parse_tx_data(tx_data, parsed_data)
|
14
13
|
|
14
|
+
# TODO: exception handling. error message should be found by errors.messages
|
15
15
|
map = connection.transact(parsed_data).get
|
16
16
|
|
17
|
+
=begin
|
18
|
+
resolve_fn = Java::ClojureLang::RT.var("datomic.api", "resolve-tempid")
|
19
|
+
tempids_key = Java::ClojureLang::Keyword.intern("tempids")
|
20
|
+
ids = map.to_java.get(tempids_key)
|
21
|
+
db = connection.db.to_java
|
22
|
+
resolve_fn.invoke(db, ids, self.dbid.to_java)
|
23
|
+
=end
|
17
24
|
resolve_changes([self], map)
|
18
25
|
|
19
26
|
map
|
@@ -122,6 +129,50 @@ module Diametric
|
|
122
129
|
end
|
123
130
|
|
124
131
|
module ClassMethods
|
132
|
+
|
133
|
+
# Create a temporary id placeholder.
|
134
|
+
#
|
135
|
+
# @param e [*#to_edn] Elements to put in the placeholder. Should
|
136
|
+
# be either partition or partition and a negative number to be
|
137
|
+
# used as a reference.
|
138
|
+
#
|
139
|
+
# @return [Diametric::Persistence::Object] Temporary id placeholder.
|
140
|
+
def tempid(*e)
|
141
|
+
if e.size == 1
|
142
|
+
return Diametric::Persistence::Peer.tempid(e[0])
|
143
|
+
elsif e.size == 2
|
144
|
+
return Diametric::Persistence::Peer.tempid(e[0], e[1])
|
145
|
+
end
|
146
|
+
nil
|
147
|
+
end
|
148
|
+
|
149
|
+
def create_schema(connection=nil)
|
150
|
+
connection ||= Diametric::Persistence::Peer.connect
|
151
|
+
connection.transact(schema)
|
152
|
+
end
|
153
|
+
|
154
|
+
def all(connection=nil, resolve=true)
|
155
|
+
connection ||= Diametric::Persistence::Peer.connect
|
156
|
+
Diametric::Query.new(self, connection, resolve).all
|
157
|
+
end
|
158
|
+
|
159
|
+
def first(conditions = {}, connection=nil, resolve=true)
|
160
|
+
connection ||= Diametric::Persistence::Peer.connect
|
161
|
+
where(conditions, connection, resolve).first
|
162
|
+
end
|
163
|
+
|
164
|
+
def where(conditions = {}, connection=nil, resolve=true)
|
165
|
+
connection ||= Diametric::Persistence::Peer.connect
|
166
|
+
query = Diametric::Query.new(self, connection, resolve)
|
167
|
+
query.where(conditions)
|
168
|
+
end
|
169
|
+
|
170
|
+
def filter(connection, *filter)
|
171
|
+
connection ||= Diametric::Persistence::Peer.connect
|
172
|
+
query = Diametric::Query.new(self, connection, true)
|
173
|
+
query.filter(*filter)
|
174
|
+
end
|
175
|
+
|
125
176
|
def get(dbid, connection=nil, resolve=false)
|
126
177
|
entity = self.new
|
127
178
|
dbid = dbid.to_i if dbid.is_a?(String)
|
@@ -137,7 +188,7 @@ module Diametric
|
|
137
188
|
else
|
138
189
|
db = conn_or_db
|
139
190
|
end
|
140
|
-
Diametric::Persistence::Peer.q(query, db, args)
|
191
|
+
Diametric::Persistence::Peer.q(query, db, args.flatten(1))
|
141
192
|
end
|
142
193
|
end
|
143
194
|
end
|
@@ -43,10 +43,36 @@ module Diametric
|
|
43
43
|
@database || Diametric::Persistence::REST.database
|
44
44
|
end
|
45
45
|
|
46
|
+
def tempid(*e)
|
47
|
+
EDN.tagged_element('db/id', e)
|
48
|
+
end
|
49
|
+
|
46
50
|
def transact(data)
|
47
51
|
connection.transact(database, data)
|
48
52
|
end
|
49
53
|
|
54
|
+
def create_schema
|
55
|
+
transact(schema)
|
56
|
+
end
|
57
|
+
|
58
|
+
def all
|
59
|
+
Diametric::Query.new(self, nil, true).all
|
60
|
+
end
|
61
|
+
|
62
|
+
def first(conditions = {})
|
63
|
+
where(conditions).first
|
64
|
+
end
|
65
|
+
|
66
|
+
def where(conditions = {})
|
67
|
+
query = Diametric::Query.new(self, nil, true)
|
68
|
+
query.where(conditions)
|
69
|
+
end
|
70
|
+
|
71
|
+
def filter(*filter)
|
72
|
+
query = Diametric::Query.new(self, nil, true)
|
73
|
+
query.filter(*filter)
|
74
|
+
end
|
75
|
+
|
50
76
|
def get(dbid, conn=nil, resolve=false)
|
51
77
|
conn ||= connection
|
52
78
|
res = conn.entity(database, dbid.to_i)
|
@@ -84,7 +110,7 @@ module Diametric
|
|
84
110
|
self.dbid = self.dbid.to_i if self.dbid.class == String
|
85
111
|
|
86
112
|
res = self.class.transact(tx_data)
|
87
|
-
if dbid.nil?
|
113
|
+
if dbid.nil? || dbid.is_a?(EDN::Type::Unknown)
|
88
114
|
self.dbid = res.data[:tempids].values.first
|
89
115
|
end
|
90
116
|
|
data/lib/diametric/query.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'diametric'
|
2
|
+
require 'edn'
|
2
3
|
|
3
4
|
module Diametric
|
4
5
|
# +Query+ objects are used to generate Datomic queries, whether to
|
@@ -15,7 +16,7 @@ module Diametric
|
|
15
16
|
class Query
|
16
17
|
include Enumerable
|
17
18
|
|
18
|
-
attr_reader :conditions, :filters, :filter_attrs, :model, :connection, :resolve
|
19
|
+
attr_reader :conditions, :filters, :filter_attrs, :filter_values, :model, :connection, :resolve
|
19
20
|
|
20
21
|
# Create a new Datomic query.
|
21
22
|
#
|
@@ -26,6 +27,7 @@ module Diametric
|
|
26
27
|
@conditions = {}
|
27
28
|
@filters = []
|
28
29
|
@filter_attrs = []
|
30
|
+
@filter_values = []
|
29
31
|
@conn_or_db = connection_or_database
|
30
32
|
@resolve = resolve
|
31
33
|
end
|
@@ -72,7 +74,7 @@ module Diametric
|
|
72
74
|
# that will be converted into a Datalog query.
|
73
75
|
# @return [Query]
|
74
76
|
def filter(*filter)
|
75
|
-
return peer_filter(filter) if self.model.instance_variable_get("@peer")
|
77
|
+
return peer_filter(*filter) if self.model.instance_variable_get("@peer")
|
76
78
|
query = self.dup
|
77
79
|
|
78
80
|
if filter.first.is_a?(EDN::Type::List)
|
@@ -87,16 +89,19 @@ module Diametric
|
|
87
89
|
|
88
90
|
def peer_filter(*filter)
|
89
91
|
query = self.dup
|
90
|
-
|
91
|
-
|
92
|
+
query.filter_attrs += (self.model.attribute_names & filter)
|
93
|
+
filter = filter.map do |e|
|
94
|
+
if e.is_a? Symbol
|
95
|
+
convert_filter_element(e)
|
96
|
+
elsif e.is_a? String
|
97
|
+
e
|
98
|
+
else
|
99
|
+
query.filter_values << e
|
100
|
+
~"?#{query.filter_attrs.last.to_s}value"
|
101
|
+
end
|
92
102
|
end
|
93
|
-
|
94
|
-
|
95
|
-
query_filter << filter[0].to_s
|
96
|
-
query_filter << "?#{filter[1].to_s}"
|
97
|
-
query_filter << filter[2..-1]
|
98
|
-
query_filter = query_filter.flatten
|
99
|
-
query.filters += [query_filter]
|
103
|
+
filter = EDN::Type::List.new(*filter)
|
104
|
+
query.filters << [Diametric::Persistence::Utils.read_string(filter.to_edn)]
|
100
105
|
query
|
101
106
|
end
|
102
107
|
|
@@ -111,7 +116,7 @@ module Diametric
|
|
111
116
|
# an appropriate error if not.
|
112
117
|
res = model.q(*data, @conn_or_db)
|
113
118
|
collapse_results(res).each do |entity|
|
114
|
-
if
|
119
|
+
if @resolve
|
115
120
|
yield model.reify(entity.first, @conn_or_db, @resolve)
|
116
121
|
elsif self.model.instance_variable_get("@peer")
|
117
122
|
yield entity
|
@@ -177,31 +182,36 @@ module Diametric
|
|
177
182
|
[(= ?ns ?include-ns)]]
|
178
183
|
EOQ
|
179
184
|
else
|
180
|
-
|
181
|
-
|
182
|
-
|
185
|
+
from = conditions.map do |k, v|
|
186
|
+
if v.kind_of? Array
|
187
|
+
[~"?#{k}",
|
188
|
+
Diametric::Persistence::Utils.read_string("...")]
|
189
|
+
else
|
190
|
+
~"?#{k}"
|
183
191
|
end
|
184
|
-
from = conditions.inject("") {|memo, kv| memo + "?#{kv.shift} "}
|
185
|
-
args = conditions.map { |_, v| v }
|
186
192
|
end
|
187
193
|
|
194
|
+
keys = conditions.keys
|
188
195
|
unless filter_attrs.empty?
|
189
|
-
|
190
|
-
|
191
|
-
memo + "[?e " + model.namespace(model.prefix, attribute) + " ?#{attribute} ] "
|
192
|
-
end
|
193
|
-
from ||= ""
|
194
|
-
from = filter_attrs.inject(from) {|from, attr| from + "?#{attr}_value "}
|
195
|
-
filter_query =
|
196
|
-
"[" +
|
197
|
-
filters.inject("") {|memo, filter| memo + "(#{filter[0]} #{filter[1]} #{filter[1]}_value) "} +
|
198
|
-
"]"
|
199
|
-
args ||= []
|
200
|
-
args = filters.inject(args) {|args, filter| args + filter[2..-1]}
|
196
|
+
from += filter_attrs.inject([]) { |memo, key| memo << ~"?#{key}value"; memo }
|
197
|
+
keys += filter_attrs
|
201
198
|
end
|
202
|
-
|
203
|
-
|
199
|
+
keys.uniq!
|
200
|
+
|
201
|
+
clauses = keys.map { |attribute|
|
202
|
+
[~"?e", model.namespace(model.prefix, attribute), ~"?#{attribute}"]
|
203
|
+
}
|
204
|
+
clauses += filters
|
204
205
|
|
206
|
+
args = conditions.map { |_, v| v }
|
207
|
+
args += filter_values
|
208
|
+
|
209
|
+
query = [
|
210
|
+
:find, ~"?e",
|
211
|
+
:in, ~"\$", from.flatten(1),
|
212
|
+
:where, *clauses
|
213
|
+
]
|
214
|
+
end
|
205
215
|
[query, args]
|
206
216
|
end
|
207
217
|
|
@@ -215,6 +225,14 @@ EOQ
|
|
215
225
|
@filters = filters
|
216
226
|
end
|
217
227
|
|
228
|
+
def filter_attrs=(filter_attrs)
|
229
|
+
@filter_attrs = filter_attrs
|
230
|
+
end
|
231
|
+
|
232
|
+
def filter_values=(filter_values)
|
233
|
+
@filter_values = filter_values
|
234
|
+
end
|
235
|
+
|
218
236
|
def convert_filter_element(element)
|
219
237
|
if element.is_a?(Symbol)
|
220
238
|
if model.attribute_names.include?(element) || @conditions.keys.include?(element)
|
@@ -6,7 +6,7 @@ module Diametric
|
|
6
6
|
class << self
|
7
7
|
def datomic_command(datomic_home)
|
8
8
|
classpath = datomic_classpath(datomic_home)
|
9
|
-
|
9
|
+
["java -server -Xmx1g", "-cp", classpath, "clojure.main", "-i", "#{datomic_home}/bin/bridge.clj", "--main datomic.rest"].flatten.join(" ")
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
@@ -14,12 +14,11 @@ module Diametric
|
|
14
14
|
attr_accessor :host, :port, :db_alias, :uri
|
15
15
|
|
16
16
|
def initialize(conf="datomic_version.yml", dest="vendor/datomic")
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@pid = nil
|
17
|
+
@conf = conf
|
18
|
+
@dest = dest
|
19
|
+
datomic_type, datomic_version = RestService.datomic_version(conf)
|
20
|
+
@datomic_home = File.join(File.dirname(__FILE__), "../..", dest, "datomic-#{datomic_type}-#{datomic_version}")
|
21
|
+
@pid = nil
|
23
22
|
end
|
24
23
|
|
25
24
|
def start(opts={})
|
@@ -51,7 +50,7 @@ module Diametric
|
|
51
50
|
end
|
52
51
|
|
53
52
|
def port_available?(uri)
|
54
|
-
|
53
|
+
Net::HTTP.get_response(uri)
|
55
54
|
false
|
56
55
|
rescue Errno::ECONNREFUSED
|
57
56
|
true
|
@@ -60,7 +59,7 @@ module Diametric
|
|
60
59
|
def ready?(uri)
|
61
60
|
while true
|
62
61
|
begin
|
63
|
-
|
62
|
+
Net::HTTP.get_response(uri)
|
64
63
|
return true
|
65
64
|
rescue
|
66
65
|
sleep 1
|
@@ -21,12 +21,12 @@ module Diametric
|
|
21
21
|
datomic_names = File.read(File.join(File.dirname(__FILE__), "../..", conf))
|
22
22
|
datomic_versions = YAML.load(datomic_names)
|
23
23
|
if ENV['DIAMETRIC_ENV'] && (ENV['DIAMETRIC_ENV'] == "pro")
|
24
|
-
datomic_versions["pro"]
|
24
|
+
return "pro", datomic_versions["pro"]
|
25
25
|
else
|
26
|
-
datomic_versions["free"]
|
26
|
+
return "free", datomic_versions["free"]
|
27
27
|
end
|
28
28
|
else
|
29
|
-
conf
|
29
|
+
return "free", conf
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -35,17 +35,17 @@ module Diametric
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def downloaded?(conf="datomic_version.yml", dest="vendor/datomic")
|
38
|
-
|
38
|
+
datomic_type, datomic_version = datomic_version(conf)
|
39
39
|
if Pathname.new(dest).relative?
|
40
40
|
dest = File.join(File.dirname(__FILE__), "..", "..", dest)
|
41
41
|
end
|
42
|
-
File.exists?(File.join(dest,
|
42
|
+
File.exists?(File.join(dest, "datomic-#{datomic_type}-#{datomic_version}"))
|
43
43
|
end
|
44
44
|
|
45
45
|
def download(conf="datomic_version.yml", dest="vendor/datomic")
|
46
46
|
return true if downloaded?(conf, dest)
|
47
|
-
version = datomic_version(conf)
|
48
|
-
url = "
|
47
|
+
type, version = datomic_version(conf)
|
48
|
+
url = "https://my.datomic.com/downloads/#{type}/#{version}"
|
49
49
|
if Pathname.new(dest).relative?
|
50
50
|
dest = File.join(File.dirname(__FILE__), "../..", dest)
|
51
51
|
end
|
data/lib/diametric/transactor.rb
CHANGED
@@ -8,7 +8,7 @@ module Diametric
|
|
8
8
|
class << self
|
9
9
|
def datomic_command(datomic_home)
|
10
10
|
classpath = datomic_classpath(datomic_home)
|
11
|
-
java_opts =
|
11
|
+
java_opts='-XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSScavengeBeforeRemark'
|
12
12
|
command = ["java -server -Xmx1g -Xms1g", java_opts, "-cp", classpath, "clojure.main", "--main datomic.launcher"].flatten.join(" ")
|
13
13
|
end
|
14
14
|
end
|
@@ -19,13 +19,14 @@ module Diametric
|
|
19
19
|
def initialize(conf="datomic_version.yml", dest="vendor/datomic")
|
20
20
|
@conf = conf
|
21
21
|
@dest = dest
|
22
|
-
|
22
|
+
datomic_type, datomic_version = Transactor.datomic_version(conf)
|
23
|
+
datomic_path = "datomic-#{datomic_type}-#{datomic_version}"
|
23
24
|
if Pathname.new(dest).relative?
|
24
|
-
@datomic_home = File.join(File.dirname(__FILE__), "../..", dest,
|
25
|
+
@datomic_home = File.join(File.dirname(__FILE__), "../..", dest, datomic_path)
|
25
26
|
else
|
26
|
-
@datomic_home = File.join(dest,
|
27
|
+
@datomic_home = File.join(dest, datomic_path)
|
27
28
|
end
|
28
|
-
|
29
|
+
#@datomic_version_no = Transactor.datomic_version_no(@datomic_version)
|
29
30
|
@hostname = nil
|
30
31
|
@port = nil
|
31
32
|
@pid = nil
|
data/lib/diametric/version.rb
CHANGED
data/lib/diametric_service.jar
CHANGED
Binary file
|
@@ -23,9 +23,9 @@ port=39082
|
|
23
23
|
|
24
24
|
|
25
25
|
# Recommended settings for -Xmx4g, ongoing usage.
|
26
|
-
memory-index-threshold=32m
|
27
|
-
memory-index-max=128m
|
28
|
-
object-cache-max=1g
|
26
|
+
# memory-index-threshold=32m
|
27
|
+
# memory-index-max=128m
|
28
|
+
# object-cache-max=1g
|
29
29
|
|
30
30
|
# Recommended settings for -Xmx4g import jobs.
|
31
31
|
# memory-index-threshold=512m
|
@@ -33,9 +33,9 @@ object-cache-max=1g
|
|
33
33
|
# object-cache-max=1g
|
34
34
|
|
35
35
|
# Recommended settings for -Xmx1g usage, e.g. dev laptops.
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
memory-index-threshold=32m
|
37
|
+
memory-index-max=128m
|
38
|
+
object-cache-max=128m
|
39
39
|
|
40
40
|
|
41
41
|
|