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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -3
  3. data/Jarfile +13 -6
  4. data/LICENSE.txt +2 -2
  5. data/README.md +57 -26
  6. data/Rakefile +1 -0
  7. data/bin/datomic-rest +1 -1
  8. data/bin/download-datomic +1 -1
  9. data/datomic_version.yml +2 -2
  10. data/diametric-java.gemspec +11 -10
  11. data/ext/diametric/DiametricCollection.java +45 -38
  12. data/ext/diametric/DiametricConnection.java +16 -15
  13. data/ext/diametric/DiametricDatabase.java +9 -8
  14. data/ext/diametric/DiametricEntity.java +104 -21
  15. data/ext/diametric/DiametricObject.java +12 -1
  16. data/ext/diametric/DiametricPeer.java +52 -31
  17. data/ext/diametric/DiametricService.java +2 -0
  18. data/ext/diametric/DiametricSet.java +11 -4
  19. data/ext/diametric/DiametricUUID.java +8 -1
  20. data/ext/diametric/DiametricUtils.java +90 -62
  21. data/lib/diametric.rb +1 -0
  22. data/lib/diametric/associations/collection.rb +103 -0
  23. data/lib/diametric/entity.rb +166 -103
  24. data/lib/diametric/persistence/common.rb +0 -44
  25. data/lib/diametric/persistence/peer.rb +53 -2
  26. data/lib/diametric/persistence/rest.rb +27 -1
  27. data/lib/diametric/query.rb +49 -31
  28. data/lib/diametric/rest_service.rb +8 -9
  29. data/lib/diametric/service_base.rb +7 -7
  30. data/lib/diametric/transactor.rb +6 -5
  31. data/lib/diametric/version.rb +1 -1
  32. data/lib/diametric_service.jar +0 -0
  33. data/spec/config/free-transactor-template.properties +6 -6
  34. data/spec/developer_query_spec.rb +17 -6
  35. data/spec/diametric/entity_spec.rb +62 -139
  36. data/spec/diametric/peer_api_spec.rb +23 -23
  37. data/spec/diametric/persistence/peer_spec.rb +73 -11
  38. data/spec/diametric/persistence/rest_spec.rb +108 -16
  39. data/spec/diametric/query_spec.rb +3 -3
  40. data/spec/diametric/rest_service_spec.rb +4 -4
  41. data/spec/diametric/schema_spec.rb +526 -0
  42. data/spec/diametric/transactor_spec.rb +5 -6
  43. data/spec/integration_spec.rb +7 -7
  44. data/spec/peer_integration_spec.rb +25 -1
  45. data/spec/peer_seattle_spec.rb +1 -2
  46. data/spec/spec_helper.rb +31 -4
  47. data/spec/support/cardinarity_many_example.rb +37 -0
  48. data/spec/support/entities.rb +127 -0
  49. data/spec/support/has_a_example.rb +31 -0
  50. data/spec/support/has_many_example.rb +79 -0
  51. data/spec/support/persistence_examples.rb +13 -5
  52. data/spec/support/various_types_examples.rb +163 -0
  53. data/spec/test_version_file.yml +2 -2
  54. 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
 
@@ -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
- if filter.first.is_a?(Array)
91
- filter = filter.first
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
- filter_attrs << filter[1].to_s
94
- query_filter = []
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 self.model.instance_variable_get("@peer") && @resolve
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
- unless conditions.empty?
181
- clauses = conditions.keys.inject("") do |memo, attribute|
182
- memo + "[?e " + model.namespace(model.prefix, attribute) + " ?#{attribute} ] "
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
- clauses ||= ""
190
- clauses = filter_attrs.inject(clauses) do |memo, attribute|
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
- query = "[:find ?e :in $ [#{from}] :where #{clauses} #{filter_query}]"
203
- end
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
- command = ["java -server -Xmx1g", "-cp", classpath, "clojure.main", "-i", "#{datomic_home}/bin/bridge.clj", "--main datomic.rest"].flatten.join(" ")
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
- @conf = conf
18
- @dest = dest
19
- @datomic_version = RestService.datomic_version(conf)
20
- @datomic_home = File.join(File.dirname(__FILE__), "../..", dest, @datomic_version)
21
- @datomic_version_no = RestService.datomic_version_no(@datomic_version)
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
- response = Net::HTTP.get_response(uri)
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
- response = Net::HTTP.get_response(uri)
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
- datomic_home = datomic_version(conf)
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, datomic_home))
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 = "http://downloads.datomic.com/#{datomic_version_no(version)}/#{version}.zip"
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
@@ -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 = "-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly"
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
- @datomic_version = Transactor.datomic_version(conf)
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, @datomic_version)
25
+ @datomic_home = File.join(File.dirname(__FILE__), "../..", dest, datomic_path)
25
26
  else
26
- @datomic_home = File.join(dest, @datomic_version)
27
+ @datomic_home = File.join(dest, datomic_path)
27
28
  end
28
- @datomic_version_no = Transactor.datomic_version_no(@datomic_version)
29
+ #@datomic_version_no = Transactor.datomic_version_no(@datomic_version)
29
30
  @hostname = nil
30
31
  @port = nil
31
32
  @pid = nil
@@ -1,3 +1,3 @@
1
1
  module Diametric
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
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
- # memory-index-threshold=32m
37
- # memory-index-max=128m
38
- # object-cache-max=128m
36
+ memory-index-threshold=32m
37
+ memory-index-max=128m
38
+ object-cache-max=128m
39
39
 
40
40
 
41
41