diametric 0.1.1-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 +7 -0
- data/Gemfile +28 -0
- data/Jarfile +20 -0
- data/LICENSE.txt +22 -0
- data/README.md +264 -0
- data/Rakefile +49 -0
- data/bin/datomic-rest +33 -0
- data/bin/download-datomic +13 -0
- data/datomic_version.yml +4 -0
- data/diametric-java.gemspec +39 -0
- data/ext/diametric/DiametricCollection.java +147 -0
- data/ext/diametric/DiametricConnection.java +113 -0
- data/ext/diametric/DiametricDatabase.java +107 -0
- data/ext/diametric/DiametricEntity.java +90 -0
- data/ext/diametric/DiametricListenableFuture.java +47 -0
- data/ext/diametric/DiametricObject.java +66 -0
- data/ext/diametric/DiametricPeer.java +414 -0
- data/ext/diametric/DiametricService.java +102 -0
- data/ext/diametric/DiametricUUID.java +61 -0
- data/ext/diametric/DiametricUtils.java +183 -0
- data/lib/boolean_type.rb +3 -0
- data/lib/diametric.rb +42 -0
- data/lib/diametric/config.rb +54 -0
- data/lib/diametric/config/environment.rb +42 -0
- data/lib/diametric/entity.rb +659 -0
- data/lib/diametric/errors.rb +13 -0
- data/lib/diametric/generators/active_model.rb +42 -0
- data/lib/diametric/persistence.rb +48 -0
- data/lib/diametric/persistence/common.rb +82 -0
- data/lib/diametric/persistence/peer.rb +154 -0
- data/lib/diametric/persistence/rest.rb +107 -0
- data/lib/diametric/query.rb +259 -0
- data/lib/diametric/railtie.rb +52 -0
- data/lib/diametric/rest_service.rb +74 -0
- data/lib/diametric/service_base.rb +77 -0
- data/lib/diametric/transactor.rb +86 -0
- data/lib/diametric/version.rb +3 -0
- data/lib/diametric_service.jar +0 -0
- data/lib/tasks/create_schema.rb +27 -0
- data/lib/tasks/diametric_config.rb +45 -0
- data/lib/value_enums.rb +8 -0
- data/spec/conf_helper.rb +55 -0
- data/spec/config/free-transactor-template.properties +73 -0
- data/spec/config/logback.xml +59 -0
- data/spec/data/seattle-data0.dtm +452 -0
- data/spec/data/seattle-data1.dtm +326 -0
- data/spec/developer_create_sample.rb +39 -0
- data/spec/developer_query_spec.rb +120 -0
- data/spec/diametric/config_spec.rb +60 -0
- data/spec/diametric/entity_spec.rb +476 -0
- data/spec/diametric/peer_api_spec.rb +147 -0
- data/spec/diametric/persistence/peer_many2many_spec.rb +76 -0
- data/spec/diametric/persistence/peer_spec.rb +27 -0
- data/spec/diametric/persistence/rest_spec.rb +30 -0
- data/spec/diametric/persistence_spec.rb +59 -0
- data/spec/diametric/query_spec.rb +118 -0
- data/spec/diametric/rest_service_spec.rb +56 -0
- data/spec/diametric/transactor_spec.rb +68 -0
- data/spec/integration_spec.rb +107 -0
- data/spec/parent_child_sample.rb +42 -0
- data/spec/peer_integration_spec.rb +121 -0
- data/spec/peer_seattle_spec.rb +200 -0
- data/spec/rc2013_seattle_big.rb +82 -0
- data/spec/rc2013_seattle_small.rb +60 -0
- data/spec/rc2013_simple_sample.rb +72 -0
- data/spec/seattle_integration_spec.rb +106 -0
- data/spec/simple_validation_sample.rb +31 -0
- data/spec/spec_helper.rb +63 -0
- data/spec/support/entities.rb +157 -0
- data/spec/support/gen_entity_class.rb +9 -0
- data/spec/support/persistence_examples.rb +104 -0
- data/spec/test_version_file.yml +4 -0
- metadata +290 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
package diametric;
|
2
|
+
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyClass;
|
5
|
+
import org.jruby.RubyObject;
|
6
|
+
import org.jruby.anno.JRubyClass;
|
7
|
+
import org.jruby.anno.JRubyMethod;
|
8
|
+
import org.jruby.javasupport.JavaUtil;
|
9
|
+
import org.jruby.runtime.ThreadContext;
|
10
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
11
|
+
|
12
|
+
import datomic.ListenableFuture;
|
13
|
+
|
14
|
+
@JRubyClass(name = "Diametric::Persistence::ListenableFuture")
|
15
|
+
public class DiametricListenableFuture extends RubyObject {
|
16
|
+
private static final long serialVersionUID = 2083281771243513904L;
|
17
|
+
// future is supposed to datomic.ListenableFuture type;
|
18
|
+
private Object future = null;
|
19
|
+
|
20
|
+
public DiametricListenableFuture(Ruby runtime, RubyClass klazz) {
|
21
|
+
super(runtime, klazz);
|
22
|
+
}
|
23
|
+
|
24
|
+
void init(Object future) {
|
25
|
+
this.future = future;
|
26
|
+
}
|
27
|
+
|
28
|
+
@JRubyMethod
|
29
|
+
public IRubyObject to_java(ThreadContext context) {
|
30
|
+
return JavaUtil.convertJavaToUsableRubyObject(context.getRuntime(), future);
|
31
|
+
}
|
32
|
+
|
33
|
+
@JRubyMethod
|
34
|
+
public IRubyObject get(ThreadContext context) {
|
35
|
+
Ruby runtime = context.getRuntime();
|
36
|
+
if (future == null) return runtime.getNil();
|
37
|
+
try {
|
38
|
+
Object result = ((ListenableFuture)future).get();
|
39
|
+
RubyClass clazz = (RubyClass)runtime.getClassFromPath("Diametric::Persistence::Object");
|
40
|
+
DiametricObject diametric_object = (DiametricObject)clazz.allocate();
|
41
|
+
diametric_object.update(result);
|
42
|
+
return diametric_object;
|
43
|
+
} catch (Throwable t) {
|
44
|
+
throw runtime.newRuntimeError(t.getMessage());
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
package diametric;
|
2
|
+
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyClass;
|
5
|
+
import org.jruby.RubyObject;
|
6
|
+
import org.jruby.anno.JRubyClass;
|
7
|
+
import org.jruby.anno.JRubyMethod;
|
8
|
+
import org.jruby.javasupport.JavaUtil;
|
9
|
+
import org.jruby.runtime.ThreadContext;
|
10
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
11
|
+
|
12
|
+
@JRubyClass(name = "Diametric::Persistence::Object")
|
13
|
+
public class DiametricObject extends RubyObject {
|
14
|
+
private static final long serialVersionUID = -4198258841171995687L;
|
15
|
+
private Object java_object = null;
|
16
|
+
|
17
|
+
public DiametricObject(Ruby runtime, RubyClass klazz) {
|
18
|
+
super(runtime, klazz);
|
19
|
+
}
|
20
|
+
|
21
|
+
void update(Object java_object) {
|
22
|
+
this.java_object = java_object;
|
23
|
+
}
|
24
|
+
|
25
|
+
@Override
|
26
|
+
public Object clone() throws CloneNotSupportedException {
|
27
|
+
return super.clone();
|
28
|
+
}
|
29
|
+
|
30
|
+
Object toJava() {
|
31
|
+
return java_object;
|
32
|
+
}
|
33
|
+
|
34
|
+
@JRubyMethod(name="new", meta=true)
|
35
|
+
public static IRubyObject rbNew(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
|
36
|
+
RubyClass clazz = (RubyClass)context.getRuntime().getClassFromPath("Diametric::Persistence::Object");
|
37
|
+
DiametricObject diametric_object = (DiametricObject)clazz.allocate();
|
38
|
+
diametric_object.update(DiametricUtils.convertRubyToJava(context, arg));
|
39
|
+
return diametric_object;
|
40
|
+
}
|
41
|
+
|
42
|
+
@JRubyMethod
|
43
|
+
public IRubyObject to_java(ThreadContext context) {
|
44
|
+
return JavaUtil.convertJavaToUsableRubyObject(context.getRuntime(), java_object);
|
45
|
+
}
|
46
|
+
|
47
|
+
@JRubyMethod(name="==", required=1)
|
48
|
+
public IRubyObject op_equal(ThreadContext context, IRubyObject arg) {
|
49
|
+
Ruby runtime = context.getRuntime();
|
50
|
+
if (arg instanceof DiametricObject) {
|
51
|
+
DiametricObject other = (DiametricObject)arg;
|
52
|
+
if (java_object.toString().equals(other.toJava().toString())) {
|
53
|
+
return runtime.getTrue();
|
54
|
+
} else {
|
55
|
+
return runtime.getFalse();
|
56
|
+
}
|
57
|
+
} else {
|
58
|
+
return runtime.getFalse();
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
@JRubyMethod
|
63
|
+
public IRubyObject to_s(ThreadContext context) {
|
64
|
+
return context.getRuntime().newString(java_object.toString());
|
65
|
+
}
|
66
|
+
}
|
@@ -0,0 +1,414 @@
|
|
1
|
+
package diametric;
|
2
|
+
|
3
|
+
import java.util.ArrayList;
|
4
|
+
import java.util.Collection;
|
5
|
+
import java.util.Iterator;
|
6
|
+
import java.util.List;
|
7
|
+
import java.util.Map;
|
8
|
+
import java.util.UUID;
|
9
|
+
|
10
|
+
import org.jruby.Ruby;
|
11
|
+
import org.jruby.RubyArray;
|
12
|
+
import org.jruby.RubyBoolean;
|
13
|
+
import org.jruby.RubyClass;
|
14
|
+
import org.jruby.RubyFixnum;
|
15
|
+
import org.jruby.RubyHash;
|
16
|
+
import org.jruby.RubyModule;
|
17
|
+
import org.jruby.RubyString;
|
18
|
+
import org.jruby.RubySymbol;
|
19
|
+
import org.jruby.anno.JRubyMethod;
|
20
|
+
import org.jruby.anno.JRubyModule;
|
21
|
+
import org.jruby.runtime.Block;
|
22
|
+
import org.jruby.runtime.ThreadContext;
|
23
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
24
|
+
|
25
|
+
import clojure.lang.PersistentHashSet;
|
26
|
+
import datomic.Connection;
|
27
|
+
import datomic.Peer;
|
28
|
+
|
29
|
+
@JRubyModule(name="Diametric::Persistence::Peer")
|
30
|
+
public class DiametricPeer extends RubyModule {
|
31
|
+
private static final long serialVersionUID = 8659857729004427581L;
|
32
|
+
|
33
|
+
protected DiametricPeer(Ruby runtime) {
|
34
|
+
super(runtime);
|
35
|
+
}
|
36
|
+
|
37
|
+
private static DiametricConnection saved_connection = null;
|
38
|
+
|
39
|
+
@JRubyMethod(meta=true)
|
40
|
+
public static IRubyObject connect(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
|
41
|
+
String uriOrMap = null;
|
42
|
+
if (arg instanceof RubyString) {
|
43
|
+
uriOrMap = DiametricUtils.rubyStringToJava(arg);
|
44
|
+
} else if (arg instanceof RubyHash) {
|
45
|
+
RubySymbol key = RubySymbol.newSymbol(context.getRuntime(), "uri");
|
46
|
+
RubyString value = (RubyString)((RubyHash)arg).op_aref(context, key);
|
47
|
+
uriOrMap = DiametricUtils.rubyStringToJava(value);
|
48
|
+
} else {
|
49
|
+
throw context.getRuntime().newArgumentError("Argument should be a String or Hash");
|
50
|
+
}
|
51
|
+
if (uriOrMap == null )
|
52
|
+
throw context.getRuntime().newArgumentError("Argument should be a String or Hash with :uri key");
|
53
|
+
|
54
|
+
RubyClass clazz = (RubyClass) context.getRuntime().getClassFromPath("Diametric::Persistence::Connection");
|
55
|
+
DiametricConnection rubyConnection = (DiametricConnection)clazz.allocate();
|
56
|
+
try {
|
57
|
+
// what value will be returned when connect fails? API doc doesn't tell anything.
|
58
|
+
Connection connection = (Connection) clojure.lang.RT.var("datomic.api", "connect").invoke(uriOrMap);
|
59
|
+
rubyConnection.init(connection);
|
60
|
+
saved_connection = rubyConnection;
|
61
|
+
return rubyConnection;
|
62
|
+
} catch (Exception e) {
|
63
|
+
// Diametric doesn't require creating database before connect.
|
64
|
+
if (e.getMessage().contains(":peer/db-not-found") && (Boolean)clojure.lang.RT.var("datomic.api", "create-database").invoke(uriOrMap)) {
|
65
|
+
Connection connection = (Connection) clojure.lang.RT.var("datomic.api", "connect").invoke(uriOrMap);
|
66
|
+
rubyConnection.init(connection);
|
67
|
+
saved_connection = rubyConnection;
|
68
|
+
return rubyConnection;
|
69
|
+
}
|
70
|
+
}
|
71
|
+
throw context.getRuntime().newRuntimeError("Failed to create connection");
|
72
|
+
}
|
73
|
+
|
74
|
+
@JRubyMethod(meta=true)
|
75
|
+
public static IRubyObject create_database(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
|
76
|
+
String uriOrMap = DiametricUtils.rubyStringToJava(arg);
|
77
|
+
if (uriOrMap == null)
|
78
|
+
throw context.getRuntime().newArgumentError("Argument should be a String");
|
79
|
+
try {
|
80
|
+
boolean status = (Boolean)clojure.lang.RT.var("datomic.api", "create-database").invoke(uriOrMap);
|
81
|
+
return RubyBoolean.newBoolean(context.getRuntime(), status);
|
82
|
+
} catch (Exception e) {
|
83
|
+
throw context.getRuntime().newRuntimeError("Datomic Error: " + e.getMessage());
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
@JRubyMethod(meta=true, required=2, rest=true)
|
88
|
+
public static IRubyObject rename_database(ThreadContext context, IRubyObject klazz, IRubyObject[] args) {
|
89
|
+
if (args.length != 2) return context.getRuntime().getNil();
|
90
|
+
String uriOrMap = DiametricUtils.rubyStringToJava(args[0]);
|
91
|
+
if (uriOrMap == null) return context.getRuntime().getNil();
|
92
|
+
String newName = DiametricUtils.rubyStringToJava(args[1]);
|
93
|
+
if (newName == null) return context.getRuntime().getNil();
|
94
|
+
try {
|
95
|
+
boolean status = (Boolean)clojure.lang.RT.var("datomic.api", "rename-database").invoke(uriOrMap, newName);
|
96
|
+
return RubyBoolean.newBoolean(context.getRuntime(), status);
|
97
|
+
} catch (Exception e) {
|
98
|
+
throw context.getRuntime().newRuntimeError("Datomic Error: " + e.getMessage());
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
@JRubyMethod(meta=true)
|
103
|
+
public static IRubyObject delete_database(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
|
104
|
+
String uriOrMap = DiametricUtils.rubyStringToJava(arg);
|
105
|
+
if (uriOrMap == null) return context.getRuntime().getNil();
|
106
|
+
try {
|
107
|
+
boolean status = (Boolean)clojure.lang.RT.var("datomic.api", "delete-database").invoke(uriOrMap);
|
108
|
+
return RubyBoolean.newBoolean(context.getRuntime(), status);
|
109
|
+
} catch (Exception e) {
|
110
|
+
throw context.getRuntime().newRuntimeError("Datomic Error: " + e.getMessage());
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
@JRubyMethod(meta=true)
|
115
|
+
public static IRubyObject shutdown(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
|
116
|
+
if (!(arg instanceof RubyBoolean)) {
|
117
|
+
throw context.getRuntime().newArgumentError("Wrong argument type.");
|
118
|
+
}
|
119
|
+
Boolean shutdownClojure = (Boolean) arg.toJava(Boolean.class);
|
120
|
+
try {
|
121
|
+
clojure.lang.RT.var("datomic.api", "shutdown").invoke(shutdownClojure);
|
122
|
+
} catch (Exception e) {
|
123
|
+
throw context.getRuntime().newRuntimeError("Datomic Error: " + e.getMessage());
|
124
|
+
}
|
125
|
+
return context.getRuntime().getNil();
|
126
|
+
}
|
127
|
+
|
128
|
+
/**
|
129
|
+
* Constructs a semi-sequential UUID useful for creating UUIDs that don't fragment indexes
|
130
|
+
*
|
131
|
+
* @param context
|
132
|
+
* @param klazz
|
133
|
+
* @return java.util.UUID. a UUID whose most significant 32 bits are currentTimeMillis rounded to seconds
|
134
|
+
*/
|
135
|
+
@JRubyMethod(meta=true)
|
136
|
+
public static IRubyObject squuid(ThreadContext context, IRubyObject klazz) {
|
137
|
+
RubyClass clazz = (RubyClass) context.getRuntime().getClassFromPath("Diametric::Persistence::UUID");
|
138
|
+
diametric.DiametricUUID ruby_uuid = (diametric.DiametricUUID)clazz.allocate();
|
139
|
+
try {
|
140
|
+
java.util.UUID java_uuid = (UUID) clojure.lang.RT.var("datomic.api", "squuid").invoke();
|
141
|
+
ruby_uuid.init(java_uuid);
|
142
|
+
return ruby_uuid;
|
143
|
+
} catch (Throwable t) {
|
144
|
+
throw context.getRuntime().newRuntimeError("Datomic Exception: " + t.getMessage());
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
/**
|
149
|
+
* Gets the time part of a squuid
|
150
|
+
*
|
151
|
+
* @param context
|
152
|
+
* @param klazz
|
153
|
+
* @param arg diametric.UUID. squuid - a UUID created by squuid()
|
154
|
+
* @return the time in the format of System.currentTimeMillis
|
155
|
+
*/
|
156
|
+
@JRubyMethod(meta=true)
|
157
|
+
public static IRubyObject squuid_time_millis(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
|
158
|
+
if (!(arg instanceof diametric.DiametricUUID)) {
|
159
|
+
throw context.getRuntime().newArgumentError("Wrong argument type.");
|
160
|
+
}
|
161
|
+
java.util.UUID squuid = ((diametric.DiametricUUID)arg).getUUID();
|
162
|
+
if (squuid == null) return context.getRuntime().getNil();
|
163
|
+
long value;
|
164
|
+
try {
|
165
|
+
value = (Long) clojure.lang.RT.var("datomic.api", "squuid-time-millis").invoke(squuid);
|
166
|
+
return RubyFixnum.newFixnum(context.getRuntime(), value);
|
167
|
+
} catch (Throwable t) {
|
168
|
+
throw context.getRuntime().newRuntimeError("Datomic Exception: " + t.getMessage());
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Generates a temp id in the designated partition
|
174
|
+
* In case the second argument is given,
|
175
|
+
* it should be an idNumber from -1 (inclusive) to -1000000 (exclusive).
|
176
|
+
*
|
177
|
+
* @param context
|
178
|
+
* @param klazz
|
179
|
+
* @param args the first argument: String. a partition, which is a keyword identifying the partition.
|
180
|
+
* @return
|
181
|
+
*/
|
182
|
+
@JRubyMethod(meta=true, required=1, optional=1)
|
183
|
+
public static IRubyObject tempid(ThreadContext context, IRubyObject klazz, IRubyObject[] args) {
|
184
|
+
if (args.length < 1 || args.length > 2) {
|
185
|
+
throw context.getRuntime().newArgumentError("Wrong number of arguments");
|
186
|
+
}
|
187
|
+
String partition = DiametricUtils.rubyStringToJava(args[0]);
|
188
|
+
RubyClass clazz = (RubyClass)context.getRuntime().getClassFromPath("Diametric::Persistence::Object");
|
189
|
+
DiametricObject diametric_object = (DiametricObject)clazz.allocate();
|
190
|
+
try {
|
191
|
+
clojure.lang.Var clj_var = clojure.lang.RT.var("datomic.api", "tempid");
|
192
|
+
if (args.length > 1 && (args[1] instanceof RubyFixnum)) {
|
193
|
+
long idNumber = (Long) args[1].toJava(Long.class);
|
194
|
+
diametric_object.update(clj_var.invoke(partition, idNumber));
|
195
|
+
} else {
|
196
|
+
diametric_object.update(clj_var.invoke(partition));
|
197
|
+
}
|
198
|
+
return diametric_object;
|
199
|
+
} catch (Throwable t) {
|
200
|
+
throw context.getRuntime().newRuntimeError(t.getMessage());
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
/**
|
205
|
+
*
|
206
|
+
* @param context
|
207
|
+
* @param klazz
|
208
|
+
* @param args Both 2 arguments should be DiametricObject.
|
209
|
+
* The first argument should hold clojure.lang.PersistentArrayMap.
|
210
|
+
* The second one should hold datomic.db.DbId.
|
211
|
+
* @return
|
212
|
+
*/
|
213
|
+
@JRubyMethod(meta=true, required=2, rest=true)
|
214
|
+
public static IRubyObject resolve_tempid(ThreadContext context, IRubyObject klazz, IRubyObject[] args) {
|
215
|
+
if (args.length != 2) {
|
216
|
+
throw context.getRuntime().newArgumentError("Wrong number of arguments");
|
217
|
+
}
|
218
|
+
Map map;
|
219
|
+
DiametricObject ruby_object;
|
220
|
+
if ((args[0] instanceof DiametricObject) && (args[1] instanceof DiametricObject)) {
|
221
|
+
map = (Map) ((DiametricObject)args[0]).toJava();
|
222
|
+
ruby_object = ((DiametricObject)args[1]);
|
223
|
+
} else {
|
224
|
+
throw context.getRuntime().newArgumentError("Wrong argument type.");
|
225
|
+
}
|
226
|
+
try {
|
227
|
+
Object dbid = clojure.lang.RT.var("datomic.api", "resolve-tempid")
|
228
|
+
.invoke(map.get(Connection.DB_AFTER), map.get(Connection.TEMPIDS), ruby_object.toJava());
|
229
|
+
ruby_object.update(dbid);
|
230
|
+
return ruby_object;
|
231
|
+
} catch (Throwable t) {
|
232
|
+
throw context.getRuntime().newRuntimeError("Datomic Exception: " + t.getMessage());
|
233
|
+
}
|
234
|
+
}
|
235
|
+
|
236
|
+
@JRubyMethod(meta=true, required=2, rest=true)
|
237
|
+
public static IRubyObject q(ThreadContext context, IRubyObject klazz, IRubyObject[] args) {
|
238
|
+
Ruby runtime = context.getRuntime();
|
239
|
+
if (args.length < 2) {
|
240
|
+
throw runtime.newArgumentError("Wrong number of arguments");
|
241
|
+
}
|
242
|
+
if (!(args[0] instanceof RubyString)) {
|
243
|
+
throw runtime.newArgumentError("The first arg should be a query string");
|
244
|
+
}
|
245
|
+
if (!(args[1] instanceof DiametricDatabase)) {
|
246
|
+
throw runtime.newArgumentError("The second arg should be a database.");
|
247
|
+
}
|
248
|
+
String query = (String)args[0].toJava(String.class);
|
249
|
+
Object database = ((DiametricDatabase)args[1]).toJava();
|
250
|
+
|
251
|
+
Collection<List<Object>> results = null;
|
252
|
+
try {
|
253
|
+
if (args.length == 2) {
|
254
|
+
results = (Collection<List<Object>>) clojure.lang.RT.var("datomic.api", "q").invoke(query, database);
|
255
|
+
} else if ((args.length == 3) && (args[2] instanceof RubyArray)) {
|
256
|
+
RubyArray ruby_inputs = (RubyArray)args[2];
|
257
|
+
if (ruby_inputs.getLength() == 0) {
|
258
|
+
results = Peer.q(query, database);
|
259
|
+
} else {
|
260
|
+
Object[] inputs = new Object[ruby_inputs.getLength()];
|
261
|
+
for (int i=0; i<inputs.length; i++) {
|
262
|
+
inputs[i] = DiametricUtils.convertRubyToJava(context, ruby_inputs.shift(context));
|
263
|
+
}
|
264
|
+
//System.out.println("OH INPUTS ARE: ");
|
265
|
+
//for (int i=0; i<inputs.length; i++) {
|
266
|
+
// System.out.println("OH: " + inputs[i]);
|
267
|
+
//}
|
268
|
+
results = (Collection<List<Object>>) clojure.lang.RT.var("datomic.api", "q").invoke(query, database, inputs);
|
269
|
+
}
|
270
|
+
} else {
|
271
|
+
Object[] inputs = new Object[args.length-2];
|
272
|
+
for (int i=0; i<inputs.length; i++) {
|
273
|
+
inputs[i] = DiametricUtils.convertRubyToJava(context, args[i+2]);
|
274
|
+
}
|
275
|
+
results = (Collection<List<Object>>) clojure.lang.RT.var("datomic.api", "q").invoke(query, database, inputs);
|
276
|
+
}
|
277
|
+
} catch (Throwable t) {
|
278
|
+
throw runtime.newRuntimeError("Datomic Exception: " + t.getMessage());
|
279
|
+
}
|
280
|
+
|
281
|
+
if (results == null) return context.getRuntime().getNil();
|
282
|
+
RubyArray ruby_results = RubyArray.newArray(context.getRuntime());
|
283
|
+
for (List list : results) {
|
284
|
+
RubyArray ruby_elements = RubyArray.newArray(context.getRuntime());
|
285
|
+
for (Object element : list) {
|
286
|
+
//System.out.println("OH ELEMENT IS: " + element + " [" + element.getClass().getCanonicalName() +"]");
|
287
|
+
ruby_elements.append(DiametricUtils.convertJavaToRuby(context, element));
|
288
|
+
}
|
289
|
+
ruby_results.append(ruby_elements);
|
290
|
+
}
|
291
|
+
return ruby_results;
|
292
|
+
}
|
293
|
+
|
294
|
+
private static List<RubyModule> bases = new ArrayList<RubyModule>();
|
295
|
+
|
296
|
+
@JRubyMethod(meta=true)
|
297
|
+
public static IRubyObject included(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
|
298
|
+
Ruby runtime = context.getRuntime();
|
299
|
+
if (arg instanceof RubyModule) {
|
300
|
+
RubyModule base = (RubyModule)arg;
|
301
|
+
bases.add(base);
|
302
|
+
base.instance_variable_set(RubyString.newString(context.getRuntime(), "@peer"), runtime.getTrue());
|
303
|
+
IRubyObject common = runtime.getClassFromPath("Diametric::Persistence::Common");
|
304
|
+
base.send(context, RubySymbol.newSymbol(runtime, "include"), common, Block.NULL_BLOCK);
|
305
|
+
IRubyObject classmethods = runtime.getClassFromPath("Diametric::Persistence::Peer::ClassMethods");
|
306
|
+
base.send(context, RubySymbol.newSymbol(runtime, "extend"), classmethods, Block.NULL_BLOCK);
|
307
|
+
}
|
308
|
+
return runtime.getNil();
|
309
|
+
}
|
310
|
+
|
311
|
+
@JRubyMethod(meta=true)
|
312
|
+
public static IRubyObject connect(ThreadContext context, IRubyObject klazz) {
|
313
|
+
if (saved_connection == null) return context.getRuntime().getNil();
|
314
|
+
return saved_connection;
|
315
|
+
}
|
316
|
+
|
317
|
+
@JRubyMethod(meta=true)
|
318
|
+
public static IRubyObject create_schemas(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
|
319
|
+
if (!(arg instanceof DiametricConnection))
|
320
|
+
throw context.getRuntime().newArgumentError("Argument should be Connection.");
|
321
|
+
IRubyObject result = context.getRuntime().getNil();
|
322
|
+
for (RubyModule base : bases) {
|
323
|
+
if (base.respondsTo("schema")) {
|
324
|
+
IRubyObject schema = base.send(context, RubySymbol.newSymbol(context.getRuntime(), "schema"), Block.NULL_BLOCK);
|
325
|
+
result = ((DiametricConnection)arg).transact(context, schema);
|
326
|
+
}
|
327
|
+
}
|
328
|
+
return result;
|
329
|
+
}
|
330
|
+
|
331
|
+
@JRubyMethod(meta=true)
|
332
|
+
public static IRubyObject transact(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
|
333
|
+
return saved_connection.transact(context, arg);
|
334
|
+
}
|
335
|
+
|
336
|
+
@JRubyMethod(meta=true)
|
337
|
+
public static IRubyObject get(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
|
338
|
+
Ruby runtime = context.getRuntime();
|
339
|
+
Object dbid = null;
|
340
|
+
if ((arg instanceof DiametricObject) && (((DiametricObject)arg).to_java(context) instanceof RubyFixnum)) {
|
341
|
+
dbid = ((DiametricObject)arg).toJava();
|
342
|
+
} else if (arg instanceof RubyFixnum) {
|
343
|
+
dbid = ((RubyFixnum)arg).toJava(Long.class);
|
344
|
+
} else {
|
345
|
+
throw runtime.newArgumentError("Argument should be dbid");
|
346
|
+
}
|
347
|
+
if (saved_connection == null) throw runtime.newRuntimeError("Connection is not established");
|
348
|
+
try {
|
349
|
+
Object database = clojure.lang.RT.var("datomic.api", "db").invoke(saved_connection.toJava());
|
350
|
+
Object entity = clojure.lang.RT.var("datomic.api", "entity").invoke(database, dbid);
|
351
|
+
RubyClass clazz = (RubyClass) context.getRuntime().getClassFromPath("Diametric::Persistence::Entity");
|
352
|
+
DiametricEntity ruby_entity = (DiametricEntity)clazz.allocate();
|
353
|
+
ruby_entity.init(entity);
|
354
|
+
return ruby_entity;
|
355
|
+
} catch (Throwable t) {
|
356
|
+
throw context.getRuntime().newRuntimeError(t.getMessage());
|
357
|
+
}
|
358
|
+
}
|
359
|
+
|
360
|
+
@JRubyMethod(meta=true)
|
361
|
+
public static IRubyObject retract_entity(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
|
362
|
+
Object dbid = DiametricUtils.convertRubyToJava(context, arg);
|
363
|
+
List query = datomic.Util.list((datomic.Util.list(":db.fn/retractEntity", dbid)));
|
364
|
+
try {
|
365
|
+
clojure.lang.RT.var("datomic.api", "transact-async").invoke(saved_connection.toJava(), query);
|
366
|
+
} catch (Throwable t) {
|
367
|
+
throw context.getRuntime().newRuntimeError("Datomic error: " + t.getMessage());
|
368
|
+
}
|
369
|
+
return context.getRuntime().getNil();
|
370
|
+
}
|
371
|
+
|
372
|
+
/**
|
373
|
+
*
|
374
|
+
* @param context
|
375
|
+
* @param klazz
|
376
|
+
* @param args database, dbid, query
|
377
|
+
* @return
|
378
|
+
*/
|
379
|
+
@JRubyMethod(meta=true, required=3, rest=true)
|
380
|
+
public static IRubyObject reverse_q(ThreadContext context, IRubyObject klazz, IRubyObject[] args) {
|
381
|
+
Ruby runtime = context.getRuntime();
|
382
|
+
if (args[0] instanceof DiametricDatabase &&
|
383
|
+
(args[1] instanceof DiametricObject || args[1] instanceof RubyFixnum) &&
|
384
|
+
args[2] instanceof RubyString) {
|
385
|
+
Object database = ((DiametricDatabase)args[0]).toJava();
|
386
|
+
Long dbid = (Long)DiametricUtils.convertRubyToJava(context, args[1]);
|
387
|
+
String query_string = (String)args[2].toJava(String.class);
|
388
|
+
try {
|
389
|
+
Object entity = clojure.lang.RT.var("datomic.api", "entity").invoke(database, dbid);
|
390
|
+
clojure.lang.PersistentHashSet set =
|
391
|
+
(PersistentHashSet) clojure.lang.RT.var("clojure.core", "get").invoke(entity, query_string);
|
392
|
+
|
393
|
+
if (set == null) {
|
394
|
+
return RubyArray.newEmptyArray(runtime);
|
395
|
+
}
|
396
|
+
|
397
|
+
RubyArray array = RubyArray.newArray(runtime, set.size());
|
398
|
+
Iterator iter = set.iterator();
|
399
|
+
while (iter.hasNext()) {
|
400
|
+
Object e = iter.next();
|
401
|
+
RubyClass clazz = (RubyClass) context.getRuntime().getClassFromPath("Diametric::Persistence::Entity");
|
402
|
+
DiametricEntity ruby_entity = (DiametricEntity)clazz.allocate();
|
403
|
+
ruby_entity.init(e);
|
404
|
+
array.append(ruby_entity);
|
405
|
+
}
|
406
|
+
return array;
|
407
|
+
} catch (Throwable t) {
|
408
|
+
throw runtime.newRuntimeError("Datomic Error: " + t.getMessage());
|
409
|
+
}
|
410
|
+
} else {
|
411
|
+
throw runtime.newArgumentError("Arguments should be 'database, dbid, query_string'");
|
412
|
+
}
|
413
|
+
}
|
414
|
+
}
|