Skip to content

Commit 3974be8

Browse files
authored
Merge pull request #414 from Backendless/vova_ya/19215/transaction_implementation
[BKNDLSS-19215]: transaction implementation
2 parents 17533d2 + 28b1217 commit 3974be8

23 files changed

+1951
-0
lines changed

src/com/backendless/UnitOfWork.java

Lines changed: 471 additions & 0 deletions
Large diffs are not rendered by default.

src/com/backendless/exceptions/ExceptionMessage.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,12 @@ public static String NULL_FIELD( String field )
153153
{
154154
return field + " cannot be null or empty.";
155155
}
156+
157+
public final static String NULL_EMPTY_BULK = "Array of objects/maps cannot be null or empty";
158+
public final static String NULL_MAP = "Entity map cannot be null";
159+
public final static String NULL_EMPTY_MAP = "Map cannot be null or empty";
160+
public final static String REF_TYPE_NOT_SUPPORT = "This operation result not supported in this operation";
161+
public final static String LIST_MAP_OR_STRING = "List can be only of objects map or objectIds";
162+
public final static String LIST_MAP_OR_STRING_OR_INSTANCES = "List can be only of objects map or objectIds or instances";
163+
public final static String LIST_OPERATIONS_NULL_EMPTY = "List of operations in unitOfWork can not be null or empty";
156164
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.backendless.transaction;
2+
3+
public interface IUnitOfWork extends UnitOfWorkCreate, UnitOfWorkDelete, UnitOfWorkUpdate, UnitOfWorkAddRelation, UnitOfWorkSetRelation, UnitOfWorkDeleteRelation, UnitOfWorkExecutor
4+
{
5+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.backendless.transaction;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
public class OpResult
7+
{
8+
private Map<String, Object> reference;
9+
private OperationType operationType;
10+
11+
public OpResult( Map<String, Object> reference, OperationType operationType )
12+
{
13+
this.reference = reference;
14+
this.operationType = operationType;
15+
}
16+
17+
public Map<String, Object> getReference()
18+
{
19+
return reference;
20+
}
21+
22+
public OperationType getOperationType()
23+
{
24+
return operationType;
25+
}
26+
27+
public Map<String, Object> resolveTo( String propName )
28+
{
29+
Map<String, Object> referencePropName = new HashMap<>( reference );
30+
referencePropName.put( UnitOfWork.PROP_NAME, propName );
31+
return referencePropName;
32+
}
33+
34+
public Map<String, Object> resolveTo( int opResultIndex )
35+
{
36+
Map<String, Object> referenceIndex = new HashMap<>( reference );
37+
referenceIndex.put( UnitOfWork.RESULT_INDEX, opResultIndex );
38+
return referenceIndex;
39+
}
40+
41+
public OpResultIndex resolveToIndex( int opResultIndex )
42+
{
43+
Map<String, Object> referenceIndex = new HashMap<>( reference );
44+
referenceIndex.put( UnitOfWork.RESULT_INDEX, opResultIndex );
45+
return new OpResultIndex( referenceIndex, operationType );
46+
}
47+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.backendless.transaction;
2+
3+
import java.util.Map;
4+
5+
public class OpResultIndex extends OpResult
6+
{
7+
public OpResultIndex( Map<String, Object> reference, OperationType operationType )
8+
{
9+
super( reference, operationType );
10+
}
11+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.backendless.transaction;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
public interface RelationOperation
7+
{
8+
// HashMap + List of hashmaps
9+
// HashMap + List of custom classes
10+
// HashMap + list of objectIds
11+
<E> OpResult addOperation( OperationType operationType, String parentTable, Map<String, Object> parentObject,
12+
String columnName, List<E> children );
13+
14+
// HashMap + OpResult=CREATE_BULK
15+
OpResult addOperation( OperationType operationType, String parentTable, Map<String, Object> parentObject,
16+
String columnName, OpResult children );
17+
18+
// HashMap + whereClause
19+
OpResult addOperation( OperationType operationType, String parentTable, Map<String, Object> parentObject,
20+
String columnName, String whereClauseForChildren );
21+
22+
// String + List of hashmaps
23+
// String + List of custom classes
24+
// String + list of objectIds
25+
<E> OpResult addOperation( OperationType operationType, String parentTable, String parentObjectId,
26+
String columnName, List<E> children );
27+
28+
// String + OpResult=CREATE_BULK
29+
OpResult addOperation( OperationType operationType, String parentTable, String parentObjectId,
30+
String columnName, OpResult children );
31+
32+
// String + whereClause
33+
OpResult addOperation( OperationType operationType, String parentTable, String parentObjectId,
34+
String columnName, String whereClauseForChildren );
35+
36+
// Custom class + List of hashmaps
37+
// Custom class + List of custom classes
38+
// Custom class + list of objectIds
39+
<E, U> OpResult addOperation( OperationType operationType, E parentObject, String columnName, List<U> children );
40+
41+
// Custom class + OpResult=CREATE_BULK
42+
<E> OpResult addOperation( OperationType operationType, E parentObject, String columnName, OpResult children );
43+
44+
// Custom class + whereClause
45+
<E> OpResult addOperation( OperationType operationType, E parentObject, String columnName,
46+
String whereClauseForChildren );
47+
48+
// OpResult=CREATE/UPDATE(getObjectId) + List of hashmaps
49+
// OpResult=CREATE/UPDATE(getObjectId) + List of custom classes
50+
// OpResult=CREATE/UPDATE(getObjectId) + List of objectIds
51+
<E> OpResult addOperation( OperationType operationType, String parentTable, OpResult parentObject,
52+
String columnName, List<E> children );
53+
54+
// OpResult=CREATE/UPDATE(getObjectId) + OpResult=CREATE_BULK
55+
OpResult addOperation( OperationType operationType, String parentTable, OpResult parentObject,
56+
String columnName, OpResult children );
57+
58+
// OpResult=CREATE/UPDATE(getObjectId) + where clause
59+
OpResult addOperation( OperationType operationType, String parentTable, OpResult parentObject,
60+
String columnName, String whereClauseForChildren );
61+
62+
// OpResult=CREATE_BULK(resultIndex) + List of hashmaps
63+
// OpResult=CREATE_BULK(resultIndex) + List of custom classes
64+
// OpResult=CREATE_BULK(resultIndex) + List of objectIds
65+
<E> OpResult addOperation( OperationType operationType, String parentTable, OpResultIndex parentObject,
66+
String columnName, List<E> children );
67+
68+
// OpResult=CREATE_BULK(resultIndex) + OpResult=CREATE_BULK
69+
OpResult addOperation( OperationType operationType, String parentTable, OpResultIndex parentObject,
70+
String columnName, OpResult children );
71+
72+
// OpResult=CREATE_BULK(resultIndex) + where clause
73+
OpResult addOperation( OperationType operationType, String parentTable, OpResultIndex parentObject,
74+
String columnName, String whereClauseForChildren );
75+
}
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
package com.backendless.transaction;
2+
3+
import com.backendless.Persistence;
4+
import com.backendless.exceptions.ExceptionMessage;
5+
import com.backendless.persistence.BackendlessSerializer;
6+
import com.backendless.transaction.operations.Operation;
7+
import com.backendless.transaction.operations.OperationAddRelation;
8+
import com.backendless.transaction.operations.OperationDeleteRelation;
9+
import com.backendless.transaction.operations.OperationSetRelation;
10+
import com.backendless.transaction.payload.Relation;
11+
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.concurrent.atomic.AtomicInteger;
15+
16+
public class RelationOperationImpl implements RelationOperation
17+
{
18+
AtomicInteger countAddRelation = new AtomicInteger( 1 );
19+
AtomicInteger countSetRelation = new AtomicInteger( 1 );
20+
AtomicInteger countDeleteRelation = new AtomicInteger( 1 );
21+
22+
private final List<Operation> operations;
23+
24+
public RelationOperationImpl( List<Operation> operations )
25+
{
26+
this.operations = operations;
27+
}
28+
29+
@Override
30+
public <E> OpResult addOperation( OperationType operationType, String parentTable,
31+
Map<String, Object> parentObject, String columnName, List<E> children )
32+
{
33+
String parentObjectId = (String) parentObject.get( Persistence.DEFAULT_OBJECT_ID_FIELD );
34+
return addOperation( operationType, parentTable, parentObjectId, columnName, children );
35+
}
36+
37+
@Override
38+
public OpResult addOperation( OperationType operationType, String parentTable,
39+
Map<String, Object> parentObject, String columnName, OpResult children )
40+
{
41+
String parentObjectId = (String) parentObject.get( Persistence.DEFAULT_OBJECT_ID_FIELD );
42+
return addOperation( operationType, parentTable, parentObjectId, columnName, children );
43+
}
44+
45+
@Override
46+
public OpResult addOperation( OperationType operationType, String parentTable, Map<String, Object> parentObject,
47+
String columnName, String whereClauseForChildren )
48+
{
49+
String parentObjectId = (String) parentObject.get( Persistence.DEFAULT_OBJECT_ID_FIELD );
50+
return addOperation( operationType, parentTable, parentObjectId, columnName, whereClauseForChildren );
51+
}
52+
53+
@Override
54+
public <E> OpResult addOperation( OperationType operationType, String parentTable, String parentObjectId,
55+
String columnName, List<E> children )
56+
{
57+
if( children == null || children.isEmpty() )
58+
throw new IllegalArgumentException( ExceptionMessage.NULL_EMPTY_BULK );
59+
60+
List<String> childrenIds = TransactionHelper.getObjectIdsFromUnknownList( children );
61+
62+
return addOperation( operationType, parentTable, parentObjectId, columnName,
63+
null, childrenIds );
64+
}
65+
66+
@Override
67+
public OpResult addOperation( OperationType operationType, String parentTable, String parentObjectId,
68+
String columnName, OpResult children )
69+
{
70+
if( !OperationType.supportResultIndexType.contains( children.getOperationType() ) )
71+
throw new IllegalArgumentException( ExceptionMessage.REF_TYPE_NOT_SUPPORT );
72+
73+
return addOperation( operationType, parentTable, parentObjectId, columnName,
74+
null, children.getReference() );
75+
}
76+
77+
@Override
78+
public OpResult addOperation( OperationType operationType, String parentTable, String parentObjectId,
79+
String columnName, String whereClauseForChildren )
80+
{
81+
return addOperation( operationType, parentTable, parentObjectId, columnName,
82+
whereClauseForChildren, null );
83+
}
84+
85+
@Override
86+
public <E, U> OpResult addOperation( OperationType operationType, E parentObject, String columnName,
87+
List<U> children )
88+
{
89+
String parentObjectId = Persistence.getEntityId( parentObject );
90+
String parentTable = BackendlessSerializer.getSimpleName( parentObject.getClass() );
91+
92+
List<String> childrenIds = TransactionHelper.getObjectIdsFromUnknownList( children );
93+
94+
return addOperation( operationType, parentTable, parentObjectId, columnName,
95+
null, childrenIds );
96+
}
97+
98+
@Override
99+
public <E> OpResult addOperation( OperationType operationType, E parentObject, String columnName,
100+
OpResult children )
101+
{
102+
String parentObjectId = Persistence.getEntityId( parentObject );
103+
String parentTable = BackendlessSerializer.getSimpleName( parentObject.getClass() );
104+
105+
if( !OperationType.supportResultIndexType.contains( children.getOperationType() ) )
106+
throw new IllegalArgumentException( ExceptionMessage.REF_TYPE_NOT_SUPPORT );
107+
108+
return addOperation( operationType, parentTable, parentObjectId, columnName,
109+
null, children.getReference() );
110+
}
111+
112+
@Override
113+
public <E> OpResult addOperation( OperationType operationType, E parentObject, String columnName,
114+
String whereClauseForChildren )
115+
{
116+
String parentObjectId = Persistence.getEntityId( parentObject );
117+
String parentTable = BackendlessSerializer.getSimpleName( parentObject.getClass() );
118+
119+
return addOperation( operationType, parentTable, parentObjectId, columnName,
120+
whereClauseForChildren, null );
121+
}
122+
123+
@Override
124+
public <E> OpResult addOperation( OperationType operationType, String parentTable, OpResult parentObject,
125+
String columnName, List<E> children )
126+
{
127+
if( children == null || children.isEmpty() )
128+
throw new IllegalArgumentException( ExceptionMessage.NULL_EMPTY_BULK );
129+
130+
List<String> childrenIds = TransactionHelper.getObjectIdsFromUnknownList( children );
131+
132+
if( !OperationType.supportEntityDescriptionResultType.contains( parentObject.getOperationType() ) )
133+
throw new IllegalArgumentException( ExceptionMessage.REF_TYPE_NOT_SUPPORT );
134+
135+
return addOperation( operationType, parentTable, parentObject.resolveTo( Persistence.DEFAULT_OBJECT_ID_FIELD ),
136+
columnName, null, childrenIds );
137+
}
138+
139+
@Override
140+
public OpResult addOperation( OperationType operationType, String parentTable, OpResult parentObject,
141+
String columnName, OpResult children )
142+
{
143+
if( !OperationType.supportEntityDescriptionResultType.contains( parentObject.getOperationType() ) )
144+
throw new IllegalArgumentException( ExceptionMessage.REF_TYPE_NOT_SUPPORT );
145+
146+
if( !OperationType.supportResultIndexType.contains( children.getOperationType() ) )
147+
throw new IllegalArgumentException( ExceptionMessage.REF_TYPE_NOT_SUPPORT );
148+
149+
return addOperation( operationType, parentTable, parentObject.resolveTo( Persistence.DEFAULT_OBJECT_ID_FIELD ),
150+
null, columnName, children.getReference() );
151+
}
152+
153+
@Override
154+
public OpResult addOperation( OperationType operationType, String parentTable, OpResult parentObject,
155+
String columnName, String whereClauseForChildren )
156+
{
157+
if( !OperationType.supportEntityDescriptionResultType.contains( parentObject.getOperationType() ) )
158+
throw new IllegalArgumentException( ExceptionMessage.REF_TYPE_NOT_SUPPORT );
159+
160+
return addOperation( operationType, parentTable, parentObject.resolveTo( Persistence.DEFAULT_OBJECT_ID_FIELD ),
161+
columnName, whereClauseForChildren, null );
162+
}
163+
164+
@Override
165+
public <E> OpResult addOperation( OperationType operationType, String parentTable, OpResultIndex parentObject,
166+
String columnName, List<E> children )
167+
{
168+
if( children == null || children.isEmpty() )
169+
throw new IllegalArgumentException( ExceptionMessage.NULL_EMPTY_BULK );
170+
171+
List<String> childrenIds = TransactionHelper.getObjectIdsFromUnknownList( children );
172+
173+
if( !OperationType.supportResultIndexType.contains( parentObject.getOperationType() ) )
174+
throw new IllegalArgumentException( ExceptionMessage.REF_TYPE_NOT_SUPPORT );
175+
176+
return addOperation( operationType, parentTable, parentObject, columnName,
177+
null, childrenIds );
178+
}
179+
180+
@Override
181+
public OpResult addOperation( OperationType operationType, String parentTable, OpResultIndex parentObject,
182+
String columnName, OpResult children )
183+
{
184+
if( !OperationType.supportEntityDescriptionResultType.contains( parentObject.getOperationType() ) )
185+
throw new IllegalArgumentException( ExceptionMessage.REF_TYPE_NOT_SUPPORT );
186+
187+
if( !OperationType.supportResultIndexType.contains( children.getOperationType() ) )
188+
throw new IllegalArgumentException( ExceptionMessage.REF_TYPE_NOT_SUPPORT );
189+
190+
return addOperation( operationType, parentTable, parentObject, null,
191+
columnName, children.getReference() );
192+
}
193+
194+
@Override
195+
public OpResult addOperation( OperationType operationType, String parentTable, OpResultIndex parentObject,
196+
String columnName, String whereClauseForChildren )
197+
{
198+
if( !OperationType.supportResultIndexType.contains( parentObject.getOperationType() ) )
199+
throw new IllegalArgumentException( ExceptionMessage.REF_TYPE_NOT_SUPPORT );
200+
201+
return addOperation( operationType, parentTable, parentObject, columnName,
202+
whereClauseForChildren, null );
203+
}
204+
205+
private OpResult addOperation( OperationType operationType, String parentTable, Object parentObject,
206+
String columnName, String whereClauseForChildren, Object children )
207+
{
208+
String operationResultId = null;
209+
210+
Relation relation = new Relation();
211+
relation.setParentObject( parentObject );
212+
relation.setRelationColumn( columnName );
213+
relation.setConditional( whereClauseForChildren );
214+
relation.setUnconditional( children );
215+
switch( operationType )
216+
{
217+
case ADD_RELATION:
218+
operationResultId = operationType + "_" + countAddRelation.getAndIncrement();
219+
operations.add( new OperationAddRelation( operationType, parentTable, operationResultId, relation ) );
220+
break;
221+
case SET_RELATION:
222+
operationResultId = operationType + "_" + countSetRelation.getAndIncrement();
223+
operations.add( new OperationSetRelation( operationType, parentTable, operationResultId, relation ) );
224+
break;
225+
case DELETE_RELATION:
226+
operationResultId = operationType + "_" + countDeleteRelation.getAndIncrement();
227+
operations.add( new OperationDeleteRelation( operationType, parentTable, operationResultId, relation ) );
228+
break;
229+
}
230+
231+
return TransactionHelper.makeOpResult( operationResultId, operationType );
232+
}
233+
}

0 commit comments

Comments
 (0)