diametric 0.1.1-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|