clazz, JsonObject object) { ... }
397 |
398 | public String toJsonString() { ... }
399 | public JsonObject toJsonObject() { ... }
400 | }
401 | ```
402 |
403 | ####Usage
404 | ```java
405 | User user = RealObject.fromJson(User.class, String string);
406 | User user = RealObject.fromJson(User.class, JsonObject object);
407 |
408 | user.toJsonString();
409 | user.toJsonObject();
410 | ```
411 |
412 | ##Migration
413 | Use Migration API in Realm-Java
414 | ```java
415 | // Auto Migration
416 | // public class BaseApplication extends Application {
417 | //
418 | // @Override
419 | // public void onCreate() {
420 | // super.onCreate();
421 | // Real.initialize(this);
422 | // Real.setAutoMigration(true);
423 | // Real.setAutoMigration(DefaultDatabase.class);
424 | // Real.setAutoMigration(SecondaryDatabase.class);
425 | // }
426 | // }
427 | ```
428 |
429 | ##More
430 |
431 |
432 | ##Author
433 | ```
434 | Name : Leonardo Taehwan Kim
435 | Email : contact@thefinestartist.com
436 | Website : http://www.thefinestartist.com
437 | ```
438 |
--------------------------------------------------------------------------------
/library/src/main/java/com/thefinestartist/royal/util/DoubleFormatUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | /* $Id$ */
19 |
20 | package com.thefinestartist.royal.util;
21 |
22 | /**
23 | * This class implements fast, thread-safe format of a double value
24 | * with a given number of decimal digits.
25 | *
26 | * The contract for the format methods is this one:
27 | * if the source is greater than or equal to 1 (in absolute value),
28 | * use the decimals parameter to define the number of decimal digits; else,
29 | * use the precision parameter to define the number of decimal digits.
30 | *
31 | * A few examples (consider decimals being 4 and precision being 8):
32 | *
33 | * - 0.0 should be rendered as "0"
34 | *
- 0.1 should be rendered as "0.1"
35 | *
- 1234.1 should be rendered as "1234.1"
36 | *
- 1234.1234567 should be rendered as "1234.1235" (note the trailing 5! Rounding!)
37 | *
- 1234.00001 should be rendered as "1234"
38 | *
- 0.00001 should be rendered as "0.00001" (here you see the effect of the "precision" parameter)
39 | *
- 0.00000001 should be rendered as "0.00000001"
40 | *
- 0.000000001 should be rendered as "0"
41 | *
42 | *
43 | * Originally authored by Julien Aymé.
44 | */
45 | public final class DoubleFormatUtil {
46 |
47 | private DoubleFormatUtil() {
48 | }
49 |
50 | /**
51 | * Rounds the given source value at the given precision
52 | * and writes the rounded value into the given target
53 | *
54 | * @param source the source value to round
55 | * @param decimals the decimals to round at (use if abs(source) ≥ 1.0)
56 | * @param precision the precision to round at (use if abs(source) < 1.0)
57 | * @param target the buffer to write to
58 | */
59 | public static void formatDouble(double source, int decimals, int precision, StringBuffer target) {
60 | int scale = (Math.abs(source) >= 1.0) ? decimals : precision;
61 | if (tooManyDigitsUsed(source, scale) || tooCloseToRound(source, scale)) {
62 | formatDoublePrecise(source, decimals, precision, target);
63 | } else {
64 | formatDoubleFast(source, decimals, precision, target);
65 | }
66 | }
67 |
68 | /**
69 | * Rounds the given source value at the given precision
70 | * and writes the rounded value into the given target
71 | *
72 | * This method internally uses the String representation of the source value,
73 | * in order to avoid any double precision computation error.
74 | *
75 | * @param source the source value to round
76 | * @param decimals the decimals to round at (use if abs(source) ≥ 1.0)
77 | * @param precision the precision to round at (use if abs(source) < 1.0)
78 | * @param target the buffer to write to
79 | */
80 | public static void formatDoublePrecise(double source, int decimals, int precision, StringBuffer target) {
81 | if (isRoundedToZero(source, decimals, precision)) {
82 | // Will always be rounded to 0
83 | target.append('0');
84 | return;
85 | } else if (Double.isNaN(source) || Double.isInfinite(source)) {
86 | // Cannot be formated
87 | target.append(Double.toString(source));
88 | return;
89 | }
90 |
91 | boolean negative = source < 0.0;
92 | if (negative) {
93 | source = -source;
94 | // Done once and for all
95 | target.append('-');
96 | }
97 | int scale = (source >= 1.0) ? decimals : precision;
98 |
99 | // The only way to format precisely the double is to use the String
100 | // representation of the double, and then to do mathematical integer operation on it.
101 | String s = Double.toString(source);
102 | if (source >= 1e-3 && source < 1e7) {
103 | // Plain representation of double: "intPart.decimalPart"
104 | int dot = s.indexOf('.');
105 | String decS = s.substring(dot + 1);
106 | int decLength = decS.length();
107 | if (scale >= decLength) {
108 | if ("0".equals(decS)) {
109 | // source is a mathematical integer
110 | target.append(s.substring(0, dot));
111 | } else {
112 | target.append(s);
113 | // Remove trailing zeroes
114 | for (int l = target.length() - 1; l >= 0 && target.charAt(l) == '0'; l--) {
115 | target.setLength(l);
116 | }
117 | }
118 | return;
119 | } else if (scale + 1 < decLength) {
120 | // ignore unnecessary digits
121 | decLength = scale + 1;
122 | decS = decS.substring(0, decLength);
123 | }
124 | long intP = Long.parseLong(s.substring(0, dot));
125 | long decP = Long.parseLong(decS);
126 | format(target, scale, intP, decP);
127 | } else {
128 | // Scientific representation of double: "x.xxxxxEyyy"
129 | int dot = s.indexOf('.');
130 | assert dot >= 0;
131 | int exp = s.indexOf('E');
132 | assert exp >= 0;
133 | int exposant = Integer.parseInt(s.substring(exp + 1));
134 | String intS = s.substring(0, dot);
135 | String decS = s.substring(dot + 1, exp);
136 | int decLength = decS.length();
137 | if (exposant >= 0) {
138 | int digits = decLength - exposant;
139 | if (digits <= 0) {
140 | // no decimal part,
141 | // no rounding involved
142 | target.append(intS);
143 | target.append(decS);
144 | for (int i = -digits; i > 0; i--) {
145 | target.append('0');
146 | }
147 | } else if (digits <= scale) {
148 | // decimal part precision is lower than scale,
149 | // no rounding involved
150 | target.append(intS);
151 | target.append(decS.substring(0, exposant));
152 | target.append('.');
153 | target.append(decS.substring(exposant));
154 | } else {
155 | // decimalDigits > scale,
156 | // Rounding involved
157 | long intP = Long.parseLong(intS) * tenPow(exposant) + Long.parseLong(decS.substring(0, exposant));
158 | long decP = Long.parseLong(decS.substring(exposant, exposant + scale + 1));
159 | format(target, scale, intP, decP);
160 | }
161 | } else {
162 | // Only a decimal part is supplied
163 | exposant = -exposant;
164 | int digits = scale - exposant + 1;
165 | if (digits < 0) {
166 | target.append('0');
167 | } else if (digits == 0) {
168 | long decP = Long.parseLong(intS);
169 | format(target, scale, 0L, decP);
170 | } else if (decLength < digits) {
171 | long decP = Long.parseLong(intS) * tenPow(decLength + 1) + Long.parseLong(decS) * 10;
172 | format(target, exposant + decLength, 0L, decP);
173 | } else {
174 | long subDecP = Long.parseLong(decS.substring(0, digits));
175 | long decP = Long.parseLong(intS) * tenPow(digits) + subDecP;
176 | format(target, scale, 0L, decP);
177 | }
178 | }
179 | }
180 | }
181 |
182 | /**
183 | * Returns true if the given source value will be rounded to zero
184 | *
185 | * @param source the source value to round
186 | * @param decimals the decimals to round at (use if abs(source) ≥ 1.0)
187 | * @param precision the precision to round at (use if abs(source) < 1.0)
188 | * @return true if the source value will be rounded to zero
189 | */
190 | private static boolean isRoundedToZero(double source, int decimals, int precision) {
191 | // Use 4.999999999999999 instead of 5 since in some cases, 5.0 / 1eN > 5e-N (e.g. for N = 37, 42, 45, 66, ...)
192 | return source == 0.0 || Math.abs(source) < 4.999999999999999 / tenPowDouble(Math.max(decimals, precision) + 1);
193 | }
194 |
195 | /**
196 | * Most used power of ten (to avoid the cost of Math.pow(10, n)
197 | */
198 | private static final long[] POWERS_OF_TEN_LONG = new long[19];
199 | private static final double[] POWERS_OF_TEN_DOUBLE = new double[30];
200 | static {
201 | POWERS_OF_TEN_LONG[0] = 1L;
202 | for (int i = 1; i < POWERS_OF_TEN_LONG.length; i++) {
203 | POWERS_OF_TEN_LONG[i] = POWERS_OF_TEN_LONG[i - 1] * 10L;
204 | }
205 | for (int i = 0; i < POWERS_OF_TEN_DOUBLE.length; i++) {
206 | POWERS_OF_TEN_DOUBLE[i] = Double.parseDouble("1e" + i);
207 | }
208 | }
209 |
210 | /**
211 | * Returns ten to the power of n
212 | *
213 | * @param n the nth power of ten to get
214 | * @return ten to the power of n
215 | */
216 | public static long tenPow(int n) {
217 | assert n >= 0;
218 | return n < POWERS_OF_TEN_LONG.length ? POWERS_OF_TEN_LONG[n] : (long) Math.pow(10, n);
219 | }
220 |
221 | private static double tenPowDouble(int n) {
222 | assert n >= 0;
223 | return n < POWERS_OF_TEN_DOUBLE.length ? POWERS_OF_TEN_DOUBLE[n] : Math.pow(10, n);
224 | }
225 |
226 | /**
227 | * Helper method to do the custom rounding used within formatDoublePrecise
228 | *
229 | * @param target the buffer to write to
230 | * @param scale the expected rounding scale
231 | * @param intP the source integer part
232 | * @param decP the source decimal part, truncated to scale + 1 digit
233 | */
234 | private static void format(StringBuffer target, int scale, long intP, long decP) {
235 | if (decP != 0L) {
236 | // decP is the decimal part of source, truncated to scale + 1 digit.
237 | // Custom rounding: add 5
238 | decP += 5L;
239 | decP /= 10L;
240 | if (decP >= tenPowDouble(scale)) {
241 | intP++;
242 | decP -= tenPow(scale);
243 | }
244 | if (decP != 0L) {
245 | // Remove trailing zeroes
246 | while (decP % 10L == 0L) {
247 | decP = decP / 10L;
248 | scale--;
249 | }
250 | }
251 | }
252 | target.append(intP);
253 | if (decP != 0L) {
254 | target.append('.');
255 | // Use tenPow instead of tenPowDouble for scale below 18,
256 | // since the casting of decP to double may cause some imprecisions:
257 | // E.g. for decP = 9999999999999999L and scale = 17,
258 | // decP < tenPow(16) while (double) decP == tenPowDouble(16)
259 | while (scale > 0 && (scale > 18 ? decP < tenPowDouble(--scale) : decP < tenPow(--scale))) {
260 | // Insert leading zeroes
261 | target.append('0');
262 | }
263 | target.append(decP);
264 | }
265 | }
266 |
267 | /**
268 | * Rounds the given source value at the given precision
269 | * and writes the rounded value into the given target
270 | *
271 | * This method internally uses double precision computation and rounding,
272 | * so the result may not be accurate (see formatDouble method for conditions).
273 | *
274 | * @param source the source value to round
275 | * @param decimals the decimals to round at (use if abs(source) ≥ 1.0)
276 | * @param precision the precision to round at (use if abs(source) < 1.0)
277 | * @param target the buffer to write to
278 | */
279 | public static void formatDoubleFast(double source, int decimals, int precision, StringBuffer target) {
280 | if (isRoundedToZero(source, decimals, precision)) {
281 | // Will always be rounded to 0
282 | target.append('0');
283 | return;
284 | } else if (Double.isNaN(source) || Double.isInfinite(source)) {
285 | // Cannot be formated
286 | target.append(Double.toString(source));
287 | return;
288 | }
289 |
290 | boolean isPositive = source >= 0.0;
291 | source = Math.abs(source);
292 | int scale = (source >= 1.0) ? decimals : precision;
293 |
294 | long intPart = (long) Math.floor(source);
295 | double tenScale = tenPowDouble(scale);
296 | double fracUnroundedPart = (source - intPart) * tenScale;
297 | long fracPart = Math.round(fracUnroundedPart);
298 | if (fracPart >= tenScale) {
299 | intPart++;
300 | fracPart = Math.round(fracPart - tenScale);
301 | }
302 | if (fracPart != 0L) {
303 | // Remove trailing zeroes
304 | while (fracPart % 10L == 0L) {
305 | fracPart = fracPart / 10L;
306 | scale--;
307 | }
308 | }
309 |
310 | if (intPart != 0L || fracPart != 0L) {
311 | // non-zero value
312 | if (!isPositive) {
313 | // negative value, insert sign
314 | target.append('-');
315 | }
316 | // append integer part
317 | target.append(intPart);
318 | if (fracPart != 0L) {
319 | // append fractional part
320 | target.append('.');
321 | // insert leading zeroes
322 | while (scale > 0 && fracPart < tenPowDouble(--scale)) {
323 | target.append('0');
324 | }
325 | target.append(fracPart);
326 | }
327 | } else {
328 | target.append('0');
329 | }
330 | }
331 |
332 | /**
333 | * Returns the exponent of the given value
334 | *
335 | * @param value the value to get the exponent from
336 | * @return the value's exponent
337 | */
338 | public static int getExponant(double value) {
339 | // See Double.doubleToRawLongBits javadoc or IEEE-754 spec
340 | // to have this algorithm
341 | long exp = Double.doubleToRawLongBits(value) & 0x7ff0000000000000L;
342 | exp = exp >> 52;
343 | return (int) (exp - 1023L);
344 | }
345 |
346 | /**
347 | * Returns true if the rounding is considered to use too many digits
348 | * of the double for a fast rounding
349 | *
350 | * @param source the source to round
351 | * @param scale the scale to round at
352 | * @return true if the rounding will potentially use too many digits
353 | */
354 | private static boolean tooManyDigitsUsed(double source, int scale) {
355 | // if scale >= 308, 10^308 ~= Infinity
356 | double decExp = Math.log10(source);
357 | return scale >= 308 || decExp + scale >= 14.5;
358 | }
359 |
360 | /**
361 | * Returns true if the given source is considered to be too close
362 | * of a rounding value for the given scale.
363 | *
364 | * @param source the source to round
365 | * @param scale the scale to round at
366 | * @return true if the source will be potentially rounded at the scale
367 | */
368 | private static boolean tooCloseToRound(double source, int scale) {
369 | source = Math.abs(source);
370 | long intPart = (long) Math.floor(source);
371 | double fracPart = (source - intPart) * tenPowDouble(scale);
372 | double decExp = Math.log10(source);
373 | double range = decExp + scale >= 12 ? .1 : .001;
374 | double distanceToRound1 = Math.abs(fracPart - Math.floor(fracPart));
375 | double distanceToRound2 = Math.abs(fracPart - Math.floor(fracPart) - 0.5);
376 | return distanceToRound1 <= range || distanceToRound2 <= range;
377 | // .001 range: Totally arbitrary range,
378 | // I never had a failure in 10e7 random tests with this value
379 | // May be JVM dependent or architecture dependent
380 | }
381 | }
--------------------------------------------------------------------------------
/library/src/androidTest/java/com/thefinestartist/royal/RoyalTransactionTest.java:
--------------------------------------------------------------------------------
1 | package com.thefinestartist.royal;
2 |
3 | import android.os.Handler;
4 | import android.os.Looper;
5 | import android.os.Message;
6 | import android.test.AndroidTestCase;
7 |
8 | import com.thefinestartist.royal.entities.Dog;
9 | import com.thefinestartist.royal.entities.DogPrimaryKey;
10 |
11 | import java.util.ArrayList;
12 | import java.util.List;
13 | import java.util.concurrent.CountDownLatch;
14 |
15 | import io.realm.Realm;
16 | import io.realm.RealmConfiguration;
17 | import io.realm.RealmObject;
18 | import io.realm.RealmQuery;
19 | import io.realm.RealmResults;
20 |
21 | /**
22 | * Created by TheFinestArtist on 7/5/15.
23 | */
24 |
25 | public class RoyalTransactionTest extends AndroidTestCase {
26 |
27 | @Override
28 | protected void setUp() throws Exception {
29 | Royal.joinWith(getContext());
30 | }
31 |
32 | @Override
33 | protected void tearDown() throws Exception {
34 | }
35 |
36 | public void testSave1() {
37 | // 1. Realm Setup
38 | RealmConfiguration realmConfig1 = new RealmConfiguration.Builder(getContext()).name("1testSave1.realm").build();
39 | Realm.deleteRealm(realmConfig1);
40 | Realm realm1 = Realm.getInstance(realmConfig1);
41 |
42 | // 2. Object Setup
43 | Dog dog1 = new Dog();
44 | dog1.setName("Kitty1");
45 |
46 | // 3. RoyalTransaction.save()
47 | RoyalTransaction.save(realm1, dog1);
48 |
49 | // 4. Query
50 | RealmQuery query = realm1.where(Dog.class);
51 | RealmResults dogs = query.findAll();
52 |
53 | // 5. Assert
54 | assertNotNull(dogs);
55 | assertEquals(1, dogs.size());
56 | assertEquals("Kitty1", dogs.get(0).getName());
57 |
58 | // 6. Realm Close
59 | realm1.close();
60 | }
61 |
62 | public void testSave2() {
63 | // 1. Realm Setup
64 | RealmConfiguration realmConfig1 = new RealmConfiguration.Builder(getContext()).name("1testSave2.realm").build();
65 | Realm.deleteRealm(realmConfig1);
66 | Realm realm1 = Realm.getInstance(realmConfig1);
67 |
68 | // 2. Object Setup
69 | Dog dog1 = new Dog();
70 | dog1.setName("Kitty1");
71 |
72 | realm1.beginTransaction();
73 | Dog dog2 = realm1.createObject(Dog.class);
74 | dog2.setName("Kitty2");
75 | realm1.commitTransaction();
76 |
77 | // 3. RoyalTransaction.save()
78 | RoyalTransaction.save(realm1, dog1, dog2);
79 |
80 | // 4. Query
81 | RealmQuery query = realm1.where(Dog.class);
82 | RealmResults dogs = query.findAll();
83 |
84 | // 5. Assert
85 | assertNotNull(dogs);
86 | assertEquals(2, dogs.size());
87 | assertEquals("Kitty2", dogs.get(0).getName());
88 | assertEquals("Kitty1", dogs.get(1).getName());
89 |
90 | // 6. Realm Close
91 | realm1.close();
92 | }
93 |
94 | public void testSave3() {
95 | // 1. Realm Setup
96 | RealmConfiguration realmConfig1 = new RealmConfiguration.Builder(getContext()).name("1testSave3.realm").build();
97 | Realm.deleteRealm(realmConfig1);
98 | Realm realm1 = Realm.getInstance(realmConfig1);
99 |
100 | RealmConfiguration realmConfig2 = new RealmConfiguration.Builder(getContext()).name("2testSave3.realm").build();
101 | Realm.deleteRealm(realmConfig2);
102 | Realm realm2 = Realm.getInstance(realmConfig2);
103 |
104 | // 2. Object Setup
105 | Dog dog1 = new Dog();
106 | dog1.setName("Kitty1");
107 |
108 | realm2.beginTransaction();
109 | Dog dog2 = realm2.createObject(Dog.class);
110 | dog2.setName("Kitty2");
111 | realm2.commitTransaction();
112 |
113 | // 3. RoyalTransaction.save()
114 | RoyalTransaction.save(realm1, dog1, dog2);
115 |
116 | // 4. Query
117 | RealmQuery query = realm1.where(Dog.class);
118 | RealmResults dogs = query.findAll();
119 |
120 | // 5. Assert
121 | assertNotNull(dogs);
122 | assertEquals(2, dogs.size());
123 | assertEquals("Kitty1", dogs.get(0).getName());
124 | assertEquals("Kitty2", dogs.get(1).getName());
125 |
126 | // 6. Realm Close
127 | realm1.close();
128 | }
129 |
130 | public void testSave4() {
131 | // 1. Realm Setup
132 | RealmConfiguration realmConfig1 = new RealmConfiguration.Builder(getContext()).name("1testSave4.realm").build();
133 | Realm.deleteRealm(realmConfig1);
134 | Realm realm1 = Realm.getInstance(realmConfig1);
135 |
136 | // 2. Object Setup
137 | DogPrimaryKey dog1 = new DogPrimaryKey();
138 | dog1.setId(1);
139 | dog1.setName("Kitty1");
140 |
141 | realm1.beginTransaction();
142 | DogPrimaryKey dog2 = realm1.createObject(DogPrimaryKey.class);
143 | dog2.setId(2);
144 | dog2.setName("Kitty2");
145 | realm1.commitTransaction();
146 |
147 | DogPrimaryKey dog3 = new DogPrimaryKey();
148 | dog3.setId(2);
149 | dog3.setName("Kitty3");
150 |
151 | DogPrimaryKey dog4 = new DogPrimaryKey();
152 | dog4.setId(3);
153 | dog4.setName("Kitty4");
154 |
155 | // 3. RoyalTransaction.save()
156 | RoyalTransaction.save(realm1, dog1, dog2, dog3, dog4);
157 |
158 | // 4. Query
159 | RealmQuery query = realm1.where(DogPrimaryKey.class);
160 | RealmResults dogs = query.findAll();
161 |
162 | // 5. Assert
163 | assertNotNull(dogs);
164 | assertEquals(3, dogs.size());
165 | assertEquals("Kitty3", dogs.get(0).getName());
166 | assertEquals("Kitty1", dogs.get(1).getName());
167 | assertEquals("Kitty4", dogs.get(2).getName());
168 |
169 | // 6. Realm Close
170 | realm1.close();
171 | }
172 |
173 | public void testSave5() {
174 | // 1. Realm Setup
175 | RealmConfiguration realmConfig1 = new RealmConfiguration.Builder(getContext()).name("1testSave5.realm").build();
176 | Realm.deleteRealm(realmConfig1);
177 | Realm realm1 = Realm.getInstance(realmConfig1);
178 |
179 | // 2. Object Setup
180 | Dog dog1 = new Dog();
181 | dog1.setName("Kitty1");
182 |
183 | // 3. RoyalTransaction.save()
184 | RoyalTransaction.save(realm1);
185 |
186 | // 4. Query
187 | RealmQuery query = realm1.where(Dog.class);
188 | RealmResults dogs = query.findAll();
189 |
190 | // 5. Assert
191 | assertNotNull(dogs);
192 | assertEquals(0, dogs.size());
193 |
194 | // 6. Realm Close
195 | realm1.close();
196 | }
197 |
198 | public void testSave6() throws InterruptedException {
199 | final CountDownLatch latch = new CountDownLatch(1);
200 | new Thread(new Runnable() {
201 | @Override
202 | public void run() {
203 | Looper.prepare();
204 |
205 | // 1. Realm Setup
206 | RealmConfiguration realmConfig1 = new RealmConfiguration.Builder(getContext()).name("1testSave6.realm").build();
207 | Realm.deleteRealm(realmConfig1);
208 | final Realm realm1 = Realm.getInstance(realmConfig1);
209 |
210 | final Handler handler = new Handler() {
211 | @Override
212 | public void handleMessage(Message msg) {
213 |
214 | // 3. RoyalTransaction.save()
215 | RoyalTransaction.save(realm1, (RealmObject) msg.obj);
216 |
217 | // 4. Query
218 | RealmQuery query = realm1.where(Dog.class);
219 | RealmResults dogs = query.findAll();
220 |
221 | // 5. Assert
222 | assertNotNull(dogs);
223 | assertEquals(1, dogs.size());
224 | assertEquals("Kitty1", dogs.get(0).getName());
225 |
226 | // 6. Realm Close
227 | realm1.close();
228 |
229 | latch.countDown();
230 | }
231 | };
232 |
233 | new Thread(new Runnable() {
234 | @Override
235 | public void run() {
236 |
237 | // 2. Object Setup
238 | Dog dog1 = new Dog();
239 | dog1.setName("Kitty1");
240 |
241 | handler.sendMessage(Message.obtain(handler, 0, dog1));
242 | }
243 | }).start();
244 |
245 | Looper.loop();
246 | }
247 | }).start();
248 | latch.await();
249 | }
250 |
251 | // public void testSave7() throws InterruptedException {
252 | // final CountDownLatch latch = new CountDownLatch(1);
253 | // new Thread(new Runnable() {
254 | // @Override
255 | // public void run() {
256 | // Looper.prepare();
257 | //
258 | // // 1. Realm Setup
259 | // RealmConfiguration realmConfig1 = new RealmConfiguration.Builder(getContext()).name("1testSave7.realm").build();
260 | // Realm.deleteRealm(realmConfig1);
261 | // final Realm realm1 = Realm.getInstance(realmConfig1);
262 | //
263 | // final Handler handler = new Handler() {
264 | // @Override
265 | // public void handleMessage(Message msg) {
266 | //
267 | // // 3. RoyalTransaction.save()
268 | // RoyalTransaction.save(realm1, (RealmObject[]) msg.obj);
269 | //
270 | // // 4. Query
271 | // RealmQuery query = realm1.where(Dog.class);
272 | // RealmResults dogs = query.findAll();
273 | //
274 | // // 5. Assert
275 | // assertNotNull(dogs);
276 | // assertEquals(2, dogs.size());
277 | // assertEquals("Kitty1", dogs.get(0).getName());
278 | // assertEquals("Kitty2", dogs.get(1).getName());
279 | //
280 | // // 6. Realm Close
281 | // realm1.close();
282 | //
283 | // latch.countDown();
284 | // }
285 | // };
286 | //
287 | // new Thread(new Runnable() {
288 | // @Override
289 | // public void run() {
290 | //
291 | // // 2. Object Setup
292 | // Dog dog1 = new Dog();
293 | // dog1.setName("Kitty1");
294 | //
295 | // RealmConfiguration realmConfig2 = new RealmConfiguration.Builder(getContext()).name("2testSave7.realm").build();
296 | // Realm.deleteRealm(realmConfig2);
297 | // Realm realm2 = Realm.getInstance(realmConfig2);
298 | //
299 | // realm2.beginTransaction();
300 | // Dog dog2 = realm2.createObject(Dog.class);
301 | // dog2.setName("Kitty2");
302 | // realm2.commitTransaction();
303 | //
304 | // handler.sendMessage(Message.obtain(handler, 0, new RealmObject[]{dog1, dog2}));
305 | // }
306 | // }).start();
307 | //
308 | // Looper.loop();
309 | // }
310 | // }).start();
311 | // latch.await();
312 | // }
313 |
314 | public void testSave8() {
315 | // 1. Realm Setup
316 | RealmConfiguration realmConfig1 = new RealmConfiguration.Builder(getContext()).name("1testSave8.realm").build();
317 | Realm.deleteRealm(realmConfig1);
318 | Realm realm1 = Realm.getInstance(realmConfig1);
319 |
320 | // 2. Object Setup
321 | Dog dog1 = new Dog();
322 | dog1.setName("Kitty1");
323 |
324 | Dog dog2 = new Dog();
325 | dog2.setAge(0);
326 | dog2.setName("Kitty2");
327 |
328 | List dogList = new ArrayList<>();
329 | dogList.add(dog2);
330 | dogList.add(dog1);
331 |
332 | // 3. RoyalTransaction.save()
333 | realm1.beginTransaction();
334 | RoyalTransaction.save(realm1, dog1, dogList);
335 | realm1.commitTransaction();
336 |
337 | // 4. Query
338 | RealmQuery query = realm1.where(Dog.class);
339 | RealmResults dogs = query.findAll();
340 |
341 | // 5. Assert
342 | assertNotNull(dogs);
343 | assertEquals(3, dogs.size());
344 | assertEquals("Kitty1", dogs.get(0).getName());
345 | assertEquals(0, dogs.get(1).getAge());
346 | assertEquals("Kitty2", dogs.get(1).getName());
347 | assertEquals("Kitty1", dogs.get(2).getName());
348 |
349 | // 6. Realm Close
350 | realm1.close();
351 | }
352 |
353 | // public void testSaveInBackground1() throws InterruptedException {
354 | // final CountDownLatch latch = new CountDownLatch(1);
355 | // new Thread(new Runnable() {
356 | // @Override
357 | // public void run() {
358 | // // 1. Realm Setup
359 | // final RealmConfiguration realmConfig1 = new RealmConfiguration.Builder(getContext()).name("1testSaveInBackground1.realm").build();
360 | // Realm.deleteRealm(realmConfig1);
361 | // Realm realm1 = Realm.getInstance(realmConfig1);
362 | //
363 | // // 2. Object Setup
364 | // Dog dog1 = new Dog();
365 | // dog1.setName("Kitty1");
366 | //
367 | // // 3. RoyalTransaction.saveInBackground()
368 | // try {
369 | // RoyalTransaction.saveInBackground(realm1, null, dog1);
370 | // fail("Please call RoyalTransaction.saveInBackground() method in main thread!! " +
371 | // "If you are not in main thread, please use RoyalTransaction.save() method :)");
372 | // } catch (IllegalStateException e) {
373 | // latch.countDown();
374 | // }
375 | //
376 | // // 6. Realm Close
377 | // realm1.close();
378 | // }
379 | // }).start();
380 | // latch.await();
381 | // }
382 |
383 | // public void testSaveInBackground2() throws InterruptedException {
384 | // final CountDownLatch latch = new CountDownLatch(1);
385 | // new Handler(getContext().getMainLooper()).post(new Runnable() {
386 | // @Override
387 | // public void run() {
388 | // // 1. Realm Setup
389 | // final RealmConfiguration realmConfig1 = new RealmConfiguration.Builder(getContext()).name("1testSaveInBackground2.realm").build();
390 | // Realm.deleteRealm(realmConfig1);
391 | // Realm realm1 = Realm.getInstance(realmConfig1);
392 | //
393 | // // 2. Object Setup
394 | // Dog dog1 = new Dog();
395 | // dog1.setName("Kitty1");
396 | //
397 | // // 3. RoyalTransaction.saveInBackground()
398 | // RoyalTransaction.saveInBackground(realm1, new OnRoyalListener() {
399 | // @Override
400 | // public void onUpdated() {
401 | // // 4. Query
402 | // Realm realm = Realm.getInstance(realmConfig1);
403 | // RealmQuery query = realm.where(Dog.class);
404 | // RealmResults dogs = query.findAll();
405 | //
406 | // // 5. Assert
407 | // assertNotNull(dogs);
408 | // assertEquals(1, dogs.size());
409 | // assertEquals("Kitty1", dogs.get(0).getName());
410 | // assertEquals(1, Thread.currentThread().getId());
411 | // latch.countDown();
412 | // }
413 | // }, dog1);
414 | //
415 | // // 6. Realm Close
416 | // realm1.close();
417 | // }
418 | // });
419 | // latch.await();
420 | // }
421 |
422 | // public void testSaveInBackground3() throws InterruptedException {
423 | // final CountDownLatch latch = new CountDownLatch(1);
424 | // new Handler(getContext().getMainLooper()).post(new Runnable() {
425 | // @Override
426 | // public void run() {
427 | // // 1. Realm Setup
428 | // final RealmConfiguration realmConfig1 = new RealmConfiguration.Builder(getContext()).name("1testSaveInBackground3.realm").build();
429 | // Realm.deleteRealm(realmConfig1);
430 | // Realm realm1 = Realm.getInstance(realmConfig1);
431 | //
432 | // RealmConfiguration realmConfig2 = new RealmConfiguration.Builder(getContext()).name("2testSaveInBackground3.realm").build();
433 | // Realm.deleteRealm(realmConfig2);
434 | // Realm realm2 = Realm.getInstance(realmConfig2);
435 | //
436 | // // 2. Object Setup
437 | // Dog dog1 = new Dog();
438 | // dog1.setName("Kitty1");
439 | //
440 | // realm2.beginTransaction();
441 | // Dog dog2 = realm2.createObject(Dog.class);
442 | // dog2.setName("Kitty2");
443 | // realm2.commitTransaction();
444 | //
445 | // // 3. RoyalTransaction.saveInBackground()
446 | // RoyalTransaction.saveInBackground(realm1, new OnRoyalUpdatedListener() {
447 | // @Override
448 | // public void onUpdated() {
449 | // // 4. Query
450 | // Realm realm = Realm.getInstance(realmConfig1);
451 | // RealmQuery query = realm.where(Dog.class);
452 | // RealmResults dogs = query.findAll();
453 | //
454 | // // 5. Assert
455 | // assertNotNull(dogs);
456 | // assertEquals(2, dogs.size());
457 | // assertEquals("Kitty1", dogs.get(0).getName());
458 | // assertEquals("Kitty2", dogs.get(1).getName());
459 | // assertEquals(1, Thread.currentThread().getId());
460 | // latch.countDown();
461 | // }
462 | // }, dog1, dog2);
463 | //
464 | // // 6. Realm Close
465 | // realm1.close();
466 | // realm2.close();
467 | // }
468 | // });
469 | // latch.await();
470 | // }
471 | }
472 |
--------------------------------------------------------------------------------