diametric 0.1.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +28 -0
  3. data/Jarfile +20 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +264 -0
  6. data/Rakefile +49 -0
  7. data/bin/datomic-rest +33 -0
  8. data/bin/download-datomic +13 -0
  9. data/datomic_version.yml +4 -0
  10. data/diametric-java.gemspec +39 -0
  11. data/ext/diametric/DiametricCollection.java +147 -0
  12. data/ext/diametric/DiametricConnection.java +113 -0
  13. data/ext/diametric/DiametricDatabase.java +107 -0
  14. data/ext/diametric/DiametricEntity.java +90 -0
  15. data/ext/diametric/DiametricListenableFuture.java +47 -0
  16. data/ext/diametric/DiametricObject.java +66 -0
  17. data/ext/diametric/DiametricPeer.java +414 -0
  18. data/ext/diametric/DiametricService.java +102 -0
  19. data/ext/diametric/DiametricUUID.java +61 -0
  20. data/ext/diametric/DiametricUtils.java +183 -0
  21. data/lib/boolean_type.rb +3 -0
  22. data/lib/diametric.rb +42 -0
  23. data/lib/diametric/config.rb +54 -0
  24. data/lib/diametric/config/environment.rb +42 -0
  25. data/lib/diametric/entity.rb +659 -0
  26. data/lib/diametric/errors.rb +13 -0
  27. data/lib/diametric/generators/active_model.rb +42 -0
  28. data/lib/diametric/persistence.rb +48 -0
  29. data/lib/diametric/persistence/common.rb +82 -0
  30. data/lib/diametric/persistence/peer.rb +154 -0
  31. data/lib/diametric/persistence/rest.rb +107 -0
  32. data/lib/diametric/query.rb +259 -0
  33. data/lib/diametric/railtie.rb +52 -0
  34. data/lib/diametric/rest_service.rb +74 -0
  35. data/lib/diametric/service_base.rb +77 -0
  36. data/lib/diametric/transactor.rb +86 -0
  37. data/lib/diametric/version.rb +3 -0
  38. data/lib/diametric_service.jar +0 -0
  39. data/lib/tasks/create_schema.rb +27 -0
  40. data/lib/tasks/diametric_config.rb +45 -0
  41. data/lib/value_enums.rb +8 -0
  42. data/spec/conf_helper.rb +55 -0
  43. data/spec/config/free-transactor-template.properties +73 -0
  44. data/spec/config/logback.xml +59 -0
  45. data/spec/data/seattle-data0.dtm +452 -0
  46. data/spec/data/seattle-data1.dtm +326 -0
  47. data/spec/developer_create_sample.rb +39 -0
  48. data/spec/developer_query_spec.rb +120 -0
  49. data/spec/diametric/config_spec.rb +60 -0
  50. data/spec/diametric/entity_spec.rb +476 -0
  51. data/spec/diametric/peer_api_spec.rb +147 -0
  52. data/spec/diametric/persistence/peer_many2many_spec.rb +76 -0
  53. data/spec/diametric/persistence/peer_spec.rb +27 -0
  54. data/spec/diametric/persistence/rest_spec.rb +30 -0
  55. data/spec/diametric/persistence_spec.rb +59 -0
  56. data/spec/diametric/query_spec.rb +118 -0
  57. data/spec/diametric/rest_service_spec.rb +56 -0
  58. data/spec/diametric/transactor_spec.rb +68 -0
  59. data/spec/integration_spec.rb +107 -0
  60. data/spec/parent_child_sample.rb +42 -0
  61. data/spec/peer_integration_spec.rb +121 -0
  62. data/spec/peer_seattle_spec.rb +200 -0
  63. data/spec/rc2013_seattle_big.rb +82 -0
  64. data/spec/rc2013_seattle_small.rb +60 -0
  65. data/spec/rc2013_simple_sample.rb +72 -0
  66. data/spec/seattle_integration_spec.rb +106 -0
  67. data/spec/simple_validation_sample.rb +31 -0
  68. data/spec/spec_helper.rb +63 -0
  69. data/spec/support/entities.rb +157 -0
  70. data/spec/support/gen_entity_class.rb +9 -0
  71. data/spec/support/persistence_examples.rb +104 -0
  72. data/spec/test_version_file.yml +4 -0
  73. metadata +290 -0
@@ -0,0 +1,102 @@
1
+ package diametric;
2
+
3
+ import java.io.IOException;
4
+
5
+ import org.jruby.Ruby;
6
+ import org.jruby.RubyClass;
7
+ import org.jruby.RubyModule;
8
+ import org.jruby.runtime.ObjectAllocator;
9
+ import org.jruby.runtime.builtin.IRubyObject;
10
+ import org.jruby.runtime.load.BasicLibraryService;
11
+
12
+ public class DiametricService implements BasicLibraryService {
13
+
14
+ @Override
15
+ public boolean basicLoad(Ruby runtime) throws IOException {
16
+ RubyModule diametric = runtime.defineModule("Diametric");
17
+ RubyModule persistence = diametric.defineModuleUnder("Persistence");
18
+
19
+ RubyModule diametric_peer = persistence.defineModuleUnder("Peer");
20
+ diametric_peer.defineAnnotatedMethods(DiametricPeer.class);
21
+
22
+ RubyClass connection = persistence.defineClassUnder("Connection", runtime.getObject(), CONNECTION_ALLOCATOR);
23
+ connection.defineAnnotatedMethods(DiametricConnection.class);
24
+
25
+ RubyClass uuid = persistence.defineClassUnder("UUID", runtime.getObject(), UUID_ALLOCATOR);
26
+ uuid.defineAnnotatedMethods(DiametricUUID.class);
27
+
28
+ RubyClass diametric_object = persistence.defineClassUnder("Object", runtime.getObject(), DIAMETRIC_OBJECT_ALLOCATOR);
29
+ diametric_object.defineAnnotatedMethods(DiametricObject.class);
30
+
31
+ RubyClass diametric_query_result = persistence.defineClassUnder("Collection", runtime.getObject(), COLLECTION_ALLOCATOR);
32
+ diametric_query_result.defineAnnotatedMethods(DiametricCollection.class);
33
+
34
+ RubyClass diametric_listenable = persistence.defineClassUnder("ListenableFuture", runtime.getObject(), LISTENABLE_ALLOCATOR);
35
+ diametric_listenable.defineAnnotatedMethods(DiametricListenableFuture.class);
36
+
37
+ RubyClass diametric_database = persistence.defineClassUnder("Database", runtime.getObject(), DATABASE_ALLOCATOR);
38
+ diametric_database.defineAnnotatedMethods(DiametricDatabase.class);
39
+
40
+ RubyClass diametric_entity = persistence.defineClassUnder("Entity", runtime.getObject(), ENTITY_ALLOCATOR);
41
+ diametric_entity.defineAnnotatedMethods(DiametricEntity.class);
42
+
43
+ RubyModule diametric_utils = persistence.defineModuleUnder("Utils");
44
+ diametric_utils.defineAnnotatedMethods(DiametricUtils.class);
45
+
46
+ setupClojureRT();
47
+
48
+ return false;
49
+ }
50
+
51
+ public static final ObjectAllocator CONNECTION_ALLOCATOR = new ObjectAllocator() {
52
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
53
+ return new DiametricConnection(runtime, klazz);
54
+ }
55
+ };
56
+
57
+ public static final ObjectAllocator UUID_ALLOCATOR = new ObjectAllocator() {
58
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
59
+ return new DiametricUUID(runtime, klazz);
60
+ }
61
+ };
62
+
63
+ public static final ObjectAllocator DIAMETRIC_OBJECT_ALLOCATOR = new ObjectAllocator() {
64
+ DiametricObject diametric_object = null;
65
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
66
+ if (diametric_object == null) diametric_object = new DiametricObject(runtime, klazz);
67
+ try {
68
+ return (DiametricObject) diametric_object.clone();
69
+ } catch (CloneNotSupportedException e) {
70
+ return new DiametricObject(runtime, klazz);
71
+ }
72
+ }
73
+ };
74
+
75
+ public static final ObjectAllocator COLLECTION_ALLOCATOR = new ObjectAllocator() {
76
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
77
+ return new DiametricCollection(runtime, klazz);
78
+ }
79
+ };
80
+
81
+ public static final ObjectAllocator LISTENABLE_ALLOCATOR = new ObjectAllocator() {
82
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
83
+ return new DiametricListenableFuture(runtime, klazz);
84
+ }
85
+ };
86
+
87
+ public static final ObjectAllocator DATABASE_ALLOCATOR = new ObjectAllocator() {
88
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
89
+ return new DiametricDatabase(runtime, klazz);
90
+ }
91
+ };
92
+
93
+ public static final ObjectAllocator ENTITY_ALLOCATOR = new ObjectAllocator() {
94
+ public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
95
+ return new DiametricEntity(runtime, klazz);
96
+ }
97
+ };
98
+
99
+ private void setupClojureRT() {
100
+ clojure.lang.RT.var("clojure.core", "require").invoke(clojure.lang.Symbol.intern("datomic.api"));
101
+ }
102
+ }
@@ -0,0 +1,61 @@
1
+ package diametric;
2
+
3
+ import java.util.UUID;
4
+
5
+ import org.jruby.Ruby;
6
+ import org.jruby.RubyClass;
7
+ import org.jruby.RubyObject;
8
+ import org.jruby.RubyString;
9
+ import org.jruby.anno.JRubyClass;
10
+ import org.jruby.anno.JRubyMethod;
11
+ import org.jruby.javasupport.JavaUtil;
12
+ import org.jruby.runtime.ThreadContext;
13
+ import org.jruby.runtime.builtin.IRubyObject;
14
+
15
+ @JRubyClass(name = "Diametric::Persistence::UUID")
16
+ public class DiametricUUID extends RubyObject {
17
+ private static final long serialVersionUID = 2083281771243513904L;
18
+ private java.util.UUID java_uuid = null;
19
+
20
+ public DiametricUUID(Ruby runtime, RubyClass klazz) {
21
+ super(runtime, klazz);
22
+ }
23
+
24
+ void init(java.util.UUID java_uuid) {
25
+ this.java_uuid = java_uuid;
26
+ }
27
+
28
+ java.util.UUID getUUID() {
29
+ return java_uuid;
30
+ }
31
+
32
+ @JRubyMethod(name = "new", meta = true)
33
+ public static IRubyObject rbNew(ThreadContext context, IRubyObject klazz) {
34
+ RubyClass clazz = (RubyClass)context.getRuntime().getClassFromPath("Diametric::Persistence::UUID");
35
+ DiametricUUID diametric_uuid = (DiametricUUID)clazz.allocate();
36
+ try {
37
+ java.util.UUID java_uuid = (UUID) clojure.lang.RT.var("datomic.api", "squuid").invoke();
38
+ diametric_uuid.init(java_uuid);
39
+ return diametric_uuid;
40
+ } catch (Throwable t) {
41
+ throw context.getRuntime().newRuntimeError(t.getMessage());
42
+ }
43
+ }
44
+
45
+ @JRubyMethod
46
+ public IRubyObject to_java(ThreadContext context) {
47
+ return JavaUtil.convertJavaToUsableRubyObject(context.getRuntime(), java_uuid);
48
+ }
49
+
50
+ @JRubyMethod
51
+ public IRubyObject to_s(ThreadContext context) {
52
+ if (java_uuid == null) return context.getRuntime().getNil();
53
+ return RubyString.newString(context.getRuntime(), java_uuid.toString());
54
+ }
55
+
56
+ @JRubyMethod
57
+ public IRubyObject generate(ThreadContext context, IRubyObject arg) {
58
+ if (java_uuid == null) return context.getRuntime().getNil();
59
+ return RubyString.newString(context.getRuntime(), java.util.UUID.randomUUID().toString());
60
+ }
61
+ }
@@ -0,0 +1,183 @@
1
+ package diametric;
2
+
3
+ import java.io.FileNotFoundException;
4
+ import java.io.FileReader;
5
+ import java.io.IOException;
6
+ import java.io.Reader;
7
+ import java.util.ArrayList;
8
+ import java.util.Collections;
9
+ import java.util.Date;
10
+ import java.util.HashMap;
11
+ import java.util.List;
12
+ import java.util.Map;
13
+ import java.util.UUID;
14
+
15
+ import org.jruby.Ruby;
16
+ import org.jruby.RubyArray;
17
+ import org.jruby.RubyBignum;
18
+ import org.jruby.RubyBoolean;
19
+ import org.jruby.RubyClass;
20
+ import org.jruby.RubyFixnum;
21
+ import org.jruby.RubyFloat;
22
+ import org.jruby.RubyHash;
23
+ import org.jruby.RubyNil;
24
+ import org.jruby.RubyString;
25
+ import org.jruby.RubyTime;
26
+ import org.jruby.anno.JRubyMethod;
27
+ import org.jruby.anno.JRubyModule;
28
+ import org.jruby.javasupport.JavaUtil;
29
+ import org.jruby.javasupport.util.RuntimeHelpers;
30
+ import org.jruby.runtime.ThreadContext;
31
+ import org.jruby.runtime.builtin.IRubyObject;
32
+
33
+ import datomic.Util;
34
+
35
+ @JRubyModule(name="Diametric::Persistence::Utils")
36
+ public class DiametricUtils {
37
+
38
+ @JRubyMethod(meta=true)
39
+ public static IRubyObject read_all(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
40
+ String filename = null;
41
+ if (arg instanceof RubyString) {
42
+ filename = DiametricUtils.rubyStringToJava(arg);
43
+ } else {
44
+ throw context.getRuntime().newArgumentError("Argument should be filename");
45
+ }
46
+ Reader reader = null;
47
+ try {
48
+ reader = new FileReader(filename);
49
+ List list = (List) Util.readAll(reader);
50
+ RubyArray array = RubyArray.newArray(context.getRuntime(), list.size());
51
+ array.addAll(list);
52
+ return array;
53
+ } catch (Exception e) {
54
+ throw context.getRuntime().newRuntimeError(e.getMessage());
55
+ } finally {
56
+ try {
57
+ if (reader != null) reader.close();
58
+ } catch (IOException e) {
59
+ // no-op
60
+ }
61
+ }
62
+ }
63
+
64
+ static String rubyStringToJava(IRubyObject arg) {
65
+ if (arg instanceof RubyString) {
66
+ // TODO probably, we need to specify encoding.
67
+ return (String) ((RubyString)arg).toJava(String.class);
68
+ } else {
69
+ return null;
70
+ }
71
+ }
72
+
73
+ static Object convertRubyToJava(ThreadContext context, IRubyObject value) {
74
+ if (value instanceof RubyString) {
75
+ String str = (String)((RubyString)value).toJava(String.class);
76
+ try {
77
+ return (Object)UUID.fromString(str);
78
+ } catch (IllegalArgumentException e) {
79
+ return (Object)str;
80
+ }
81
+ }
82
+ if (value instanceof RubyBoolean) return (Object)((RubyBoolean)value).toJava(Boolean.class);
83
+ if (value instanceof RubyFixnum) return (Object)((RubyFixnum)value).toJava(Long.class);
84
+ if (value instanceof DiametricUUID) return ((DiametricUUID)value).getUUID();
85
+ if (value instanceof RubyBignum) {
86
+ RubyString svalue = (RubyString)((RubyBignum)value).to_s();
87
+ java.math.BigInteger bivalue = new java.math.BigInteger((String)svalue.toJava(String.class));
88
+ return (Object)bivalue;
89
+ }
90
+ if (value instanceof RubyFloat) return (Object)((RubyFloat)value).toJava(Double.class);
91
+ if (value instanceof RubyTime) {
92
+ RubyTime tmvalue = (RubyTime)value;
93
+ return (Object)tmvalue.getJavaDate();
94
+ }
95
+ if (value.respondsTo("to_time")) {
96
+ // DateTime or Date
97
+ RubyTime tmvalue = (RubyTime)RuntimeHelpers.invoke(context, value, "to_time");
98
+ return (Object)tmvalue.getJavaDate();
99
+ }
100
+ //System.out.println("NOT YET CONVERTED");
101
+ //System.out.println("RESPONDSTO? TO_A:" + value.respondsTo("to_a"));
102
+ if (value.respondsTo("to_a")) { // might be Set for cardinality many type
103
+ RubyArray ruby_array = (RubyArray)RuntimeHelpers.invoke(context, value, "to_a");
104
+ List<Object> list = new ArrayList<Object>();
105
+ while (true) {
106
+ IRubyObject element = ruby_array.shift(context);
107
+ if (element.isNil()) break;
108
+ list.add(DiametricUtils.convertRubyToJava(context, element));
109
+ }
110
+ return Collections.unmodifiableList(list);
111
+ }
112
+ if (value instanceof DiametricObject) {
113
+ return ((DiametricObject)value).toJava();
114
+ }
115
+ return (Object)value.toJava(Object.class);
116
+ }
117
+
118
+ static IRubyObject convertJavaToRuby(ThreadContext context, Object value) {
119
+ Ruby runtime = context.getRuntime();
120
+ if (value instanceof String) return RubyString.newString(runtime, (String)value);
121
+ if (value instanceof Boolean) return RubyBoolean.newBoolean(runtime, (Boolean)value);
122
+ if (value instanceof Long) return RubyFixnum.newFixnum(runtime, (Long)value);
123
+ if (value instanceof clojure.lang.Keyword) {
124
+ return RubyString.newString(runtime, ((clojure.lang.Keyword)value).toString());
125
+ }
126
+ if (value instanceof java.math.BigInteger) return RubyBignum.newBignum(runtime, ((java.math.BigInteger)value).longValue());
127
+ if (value instanceof Double) return RubyFloat.newFloat(runtime, (Double)value);
128
+ if (value instanceof Date) return RubyTime.newTime(runtime, ((Date)value).getTime());
129
+ if (value instanceof java.util.UUID) {
130
+ RubyClass clazz = (RubyClass)context.getRuntime().getClassFromPath("Diametric::Persistence::UUID");
131
+ DiametricUUID diametric_uuid = (DiametricUUID)clazz.allocate();
132
+ diametric_uuid.init((java.util.UUID)value);
133
+ return diametric_uuid;
134
+ }
135
+ return JavaUtil.convertJavaToUsableRubyObject(runtime, value);
136
+ }
137
+
138
+ static List<Object> convertRubyTxDataToJava(ThreadContext context, IRubyObject arg) {
139
+ List<Object> tx_data = null;
140
+ if (arg instanceof RubyArray) {
141
+ tx_data = fromRubyArray(context, arg);
142
+ } else {
143
+ Object obj = arg.toJava(Object.class);
144
+ if (obj instanceof clojure.lang.PersistentVector) {
145
+ tx_data = (clojure.lang.PersistentVector)obj;
146
+ }
147
+ }
148
+ return tx_data;
149
+ }
150
+
151
+ private static List<Object> fromRubyArray(ThreadContext context, IRubyObject arg) {
152
+ RubyArray ruby_tx_data = (RubyArray)arg;
153
+ List<Object> java_tx_data = new ArrayList<Object>();
154
+ for (int i=0; i<ruby_tx_data.getLength(); i++) {
155
+ IRubyObject element = (IRubyObject) ruby_tx_data.get(i);
156
+ if (element instanceof RubyHash) {
157
+ RubyHash ruby_hash = (RubyHash) element;
158
+ Map<Object, Object> keyvals = new HashMap<Object, Object>();
159
+ while (true) {
160
+ IRubyObject pair = ruby_hash.shift(context);
161
+ if (pair instanceof RubyNil) break;
162
+ Object key = DiametricUtils.convertRubyToJava(context, ((RubyArray) pair).shift(context));
163
+ Object value = DiametricUtils.convertRubyToJava(context, ((RubyArray) pair).shift(context));
164
+ keyvals.put(key, value);
165
+ }
166
+ java_tx_data.add(Collections.unmodifiableMap(keyvals));
167
+ } else if (element instanceof RubyArray) {
168
+ RubyArray ruby_array = (RubyArray) element;
169
+ List<Object> keyvals = new ArrayList<Object>();
170
+ while (true) {
171
+ IRubyObject ruby_element = ruby_array.shift(context);
172
+ if (ruby_element instanceof RubyNil) break;
173
+ Object key_or_value = DiametricUtils.convertRubyToJava(context, ruby_element);
174
+ keyvals.add(key_or_value);
175
+ }
176
+ java_tx_data.add(Collections.unmodifiableList(keyvals));
177
+ } else {
178
+ continue;
179
+ }
180
+ }
181
+ return java_tx_data;
182
+ }
183
+ }
@@ -0,0 +1,3 @@
1
+ module Boolean; end
2
+ class TrueClass; include Boolean; end
3
+ class FalseClass; include Boolean; end
@@ -0,0 +1,42 @@
1
+ require "diametric/version"
2
+ require "diametric/entity"
3
+ require "diametric/query"
4
+ require "diametric/persistence"
5
+ require "diametric/errors"
6
+
7
+ require 'diametric/config'
8
+
9
+ def is_jruby?
10
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
11
+ true
12
+ else
13
+ false
14
+ end
15
+ end
16
+
17
+ if is_jruby?
18
+ require 'lock_jar'
19
+ jar_file = File.join(File.dirname(__FILE__), "..", "Jarfile")
20
+ lock_file = File.join(File.dirname(__FILE__), "..", "Jarfile.lock")
21
+ current_dir = Dir.pwd
22
+ Dir.chdir(File.dirname(lock_file))
23
+ LockJar.lock(jar_file)
24
+ LockJar.install(lock_file)
25
+ LockJar.load(lock_file)
26
+ Dir.chdir(current_dir)
27
+
28
+ require 'diametric_service.jar'
29
+ require 'diametric/diametric'
30
+ require 'diametric/persistence/peer'
31
+ end
32
+
33
+ if defined?(Rails)
34
+ require 'diametric/railtie'
35
+ end
36
+
37
+ # Diametric is a library for building schemas, queries, and
38
+ # transactions for Datomic from Ruby objects. It is also used to map
39
+ # Ruby objects as entities into a Datomic database.
40
+ module Diametric
41
+ extend Diametric::Config
42
+ end
@@ -0,0 +1,54 @@
1
+ require 'diametric/config/environment'
2
+ require 'diametric/persistence'
3
+
4
+ module Diametric
5
+ # Program-level configuration services including configuration loading and base connections.
6
+ module Config
7
+ extend self
8
+
9
+ # The current configuration Diametric will use in {#connect!}
10
+ #
11
+ # @return [Hash]
12
+ def configuration
13
+ @configuration ||= {}
14
+ end
15
+
16
+ # Determine if Diametric has been configured
17
+ #
18
+ # @return [Boolean]
19
+ def configured?
20
+ configuration.present?
21
+ end
22
+
23
+ # Load settings from a compliant diametric.yml file and make a connection. This can be used for
24
+ # easy setup with frameworks other than Rails.
25
+ #
26
+ # See {Persistence} for valid options.
27
+ #
28
+ # @example Configure Diametric.
29
+ # Diametric.load_and_connect!("/path/to/diametric.yml")
30
+ #
31
+ # @param [ String ] path The path to the file.
32
+ # @param [ String, Symbol ] environment The environment to load.
33
+ def load_and_connect!(path, environment = nil)
34
+ settings = Environment.load_yaml(path, environment)
35
+ @configuration = settings.with_indifferent_access
36
+ connect!(configuration)
37
+ peer_setup if Diametric::Persistence.peer?
38
+ configuration
39
+ end
40
+
41
+ # Establish a base connection from the supplied configuration hash.
42
+ #
43
+ # @param [ Hash ] configuration The configuration of the database to connect to. See {Persistence.establish_base_connection} for valid options.
44
+ def connect!(configuration)
45
+ ::Diametric::Persistence.establish_base_connection(configuration)
46
+ end
47
+
48
+ private
49
+ def peer_setup
50
+ load File.join(File.dirname(__FILE__), '..', 'tasks', 'create_schema.rb')
51
+ Rake::Task["diametric:create_schema_for_peer"].invoke
52
+ end
53
+ end
54
+ end