1
1
part of flutter_parse_sdk;
2
2
3
3
abstract class ParseBase {
4
- String className ;
4
+ String parseClassName ;
5
5
Type type;
6
-
7
- String setClassName (String className) => this .className = className;
8
-
9
- String getClassName () => className;
6
+ bool _dirty = false ; // reserved property
7
+ final Map <String , dynamic > _unsavedChanges = Map <String , dynamic >();
8
+ final Map <String , dynamic > _savingChanges = Map <String , dynamic >();
10
9
11
10
/// Stores all the values of a class
12
11
Map <String , dynamic > _objectData = Map <String , dynamic >();
@@ -16,6 +15,40 @@ abstract class ParseBase {
16
15
17
16
set objectId (String objectId) => set <String >(keyVarObjectId, objectId);
18
17
18
+ bool isDirty ({String key}) {
19
+ if (key != null ) {
20
+ return _unsavedChanges[key] != null ;
21
+ }
22
+ return _isDirty (true );
23
+ }
24
+
25
+ bool _isDirty (bool considerChildren) {
26
+ if (_dirty || _unsavedChanges.isNotEmpty) {
27
+ return true ;
28
+ }
29
+
30
+ if (considerChildren) {
31
+ return _areChildrenDirty (Set <dynamic >());
32
+ }
33
+ return false ;
34
+ }
35
+
36
+ bool _areChildrenDirty (Set <dynamic > seenObjects) {
37
+ if (seenObjects.contains (this )) {
38
+ return false ;
39
+ }
40
+ seenObjects.add (this );
41
+ if (_dirty || _unsavedChanges.isNotEmpty) {
42
+ return true ;
43
+ }
44
+ _getObjectData ().forEach ((String key, dynamic value) {
45
+ if (value is ParseObject && value._areChildrenDirty (seenObjects)) {
46
+ return true ;
47
+ }
48
+ });
49
+ return false ;
50
+ }
51
+
19
52
/// Returns [DateTime] createdAt
20
53
DateTime get createdAt {
21
54
if (get <dynamic >(keyVarCreatedAt) is String ) {
@@ -40,7 +73,7 @@ abstract class ParseBase {
40
73
@protected
41
74
Map <String , dynamic > toJson ({bool full, bool forApiRQ = false }) {
42
75
final Map <String , dynamic > map = < String , dynamic > {
43
- keyVarClassName: className ,
76
+ keyVarClassName: parseClassName ,
44
77
};
45
78
46
79
if (objectId != null ) {
@@ -55,7 +88,8 @@ abstract class ParseBase {
55
88
map[keyVarUpdatedAt] = _parseDateFormat.format (updatedAt);
56
89
}
57
90
58
- getObjectData ().forEach ((String key, dynamic value) {
91
+ final Map <String , dynamic > target = forApiRQ ? _unsavedChanges : _getObjectData ();
92
+ target.forEach ((String key, dynamic value) {
59
93
if (! map.containsKey (key)) {
60
94
map[key] = parseEncode (value, full: full);
61
95
}
@@ -81,7 +115,7 @@ abstract class ParseBase {
81
115
}
82
116
83
117
objectData.forEach ((String key, dynamic value) {
84
- if (key == className || key == '__type' ) {
118
+ if (key == parseClassName || key == '__type' ) {
85
119
// NO OP
86
120
} else if (key == keyVarObjectId) {
87
121
objectId = value;
@@ -98,9 +132,9 @@ abstract class ParseBase {
98
132
set <DateTime >(keyVarUpdatedAt, value);
99
133
}
100
134
} else if (key == keyVarAcl) {
101
- getObjectData () [keyVarAcl] = ParseACL ().fromJson (value);
135
+ this [keyVarAcl] = ParseACL ().fromJson (value);
102
136
} else {
103
- getObjectData () [key] = parseDecode (value);
137
+ this [key] = parseDecode (value);
104
138
}
105
139
});
106
140
@@ -113,17 +147,32 @@ abstract class ParseBase {
113
147
114
148
/// Sets all the objects variables
115
149
@protected
116
- void setObjectData (Map <String , dynamic > objectData) =>
150
+ void _setObjectData (Map <String , dynamic > objectData) =>
117
151
_objectData = objectData;
118
152
119
153
/// Returns the objects variables
120
154
@protected
121
- Map <String , dynamic > getObjectData () => _objectData ?? Map <String , dynamic >();
155
+ Map <String , dynamic > _getObjectData () => _objectData ?? Map <String , dynamic >();
156
+
157
+ bool containsValue (Object value) {
158
+ return _getObjectData ().containsValue (value);
159
+ }
122
160
161
+ bool containsKey (Object key) {
162
+ return _getObjectData ().containsKey (key);
163
+ }
164
+
165
+ dynamic operator [](Object key) {
166
+ get <dynamic >(key);
167
+ }
168
+
169
+ void operator []= (String key, dynamic value) {
170
+ set <dynamic >(key, value);
171
+ }
123
172
/// Saves in storage
124
173
Future <void > saveInStorage (String key) async {
125
174
final String objectJson = json.encode (toJson (full: true ));
126
- await ParseCoreData ().getStore ()
175
+ ParseCoreData ().getStore ()
127
176
..setString (key, objectJson);
128
177
}
129
178
@@ -134,25 +183,29 @@ abstract class ParseBase {
134
183
/// needed or not, set to false
135
184
void set <T >(String key, T value, {bool forceUpdate = true }) {
136
185
if (value != null ) {
137
- if (getObjectData ().containsKey (key)) {
186
+ if (_getObjectData ().containsKey (key)) {
187
+ if (_getObjectData ()[key] == value) {
188
+ return ;
189
+ }
138
190
if (forceUpdate) {
139
- getObjectData ()[key] = value;
191
+ _getObjectData ()[key] = value;
140
192
}
141
193
} else {
142
- getObjectData ()[key] = value;
194
+ _getObjectData ()[key] = value;
143
195
}
196
+ _unsavedChanges[key] = value;
144
197
}
145
198
}
146
199
147
200
///Set the [ParseACL] governing this object.
148
201
void setACL <ParseACL >(ParseACL acl) {
149
- getObjectData ()[keyVarAcl] = acl;
202
+ _getObjectData ()[keyVarAcl] = acl;
150
203
}
151
204
152
205
///Access the [ParseACL] governing this object.
153
206
ParseACL getACL () {
154
- if (getObjectData ().containsKey (keyVarAcl)) {
155
- return getObjectData ()[keyVarAcl];
207
+ if (_getObjectData ().containsKey (keyVarAcl)) {
208
+ return _getObjectData ()[keyVarAcl];
156
209
} else {
157
210
return ParseACL ();
158
211
}
@@ -164,12 +217,12 @@ abstract class ParseBase {
164
217
/// getType<int> and an int will be returned, null, or a defaultValue if
165
218
/// provided
166
219
dynamic get <T >(String key, {T defaultValue}) {
167
- if (getObjectData ().containsKey (key)) {
168
- if (T != null && getObjectData ()[key] is T ) {
169
- final T data = getObjectData ()[key];
220
+ if (_getObjectData ().containsKey (key)) {
221
+ if (T != null && _getObjectData ()[key] is T ) {
222
+ final T data = _getObjectData ()[key];
170
223
return data;
171
224
} else {
172
- return getObjectData ()[key];
225
+ return _getObjectData ()[key];
173
226
}
174
227
} else {
175
228
return defaultValue;
@@ -184,7 +237,7 @@ abstract class ParseBase {
184
237
await unpin ();
185
238
final Map <String , dynamic > objectMap = parseEncode (this , full: true );
186
239
final String json = jsonEncode (objectMap);
187
- await ParseCoreData ().getStore ()
240
+ ParseCoreData ().getStore ()
188
241
..setString (objectId, json);
189
242
return true ;
190
243
} else {
@@ -197,7 +250,7 @@ abstract class ParseBase {
197
250
/// Replicates Android SDK pin process and saves object to storage
198
251
Future <bool > unpin ({String key}) async {
199
252
if (objectId != null ) {
200
- await ParseCoreData ().getStore ()
253
+ ParseCoreData ().getStore ()
201
254
..remove (key ?? objectId);
202
255
return true ;
203
256
}
@@ -210,7 +263,7 @@ abstract class ParseBase {
210
263
/// Replicates Android SDK pin process and saves object to storage
211
264
dynamic fromPin (String objectId) async {
212
265
if (objectId != null ) {
213
- final CoreStore coreStore = await ParseCoreData ().getStore ();
266
+ final CoreStore coreStore = ParseCoreData ().getStore ();
214
267
final String itemFromStore = await coreStore.getString (objectId);
215
268
216
269
if (itemFromStore != null ) {
@@ -220,5 +273,19 @@ abstract class ParseBase {
220
273
return null ;
221
274
}
222
275
223
- Map <String , dynamic > toPointer () => encodeObject (className, objectId);
276
+ Map <String , dynamic > toPointer () => encodeObject (parseClassName, objectId);
277
+
278
+ /// Deprecated
279
+ @Deprecated ('Prefer to use parseClassName' )
280
+ String className;
281
+ @Deprecated ('Prefer to use parseClassName' )
282
+ String getClassName () => parseClassName;
283
+ @Deprecated ('Prefer to use parseClassName' )
284
+ String setClassName (String className) => parseClassName = className;
285
+ @protected @Deprecated ('Prefer to use _getObjectData method, or operator [] for certain key.' )
286
+ Map <String , dynamic > getObjectData () => _getObjectData ();
287
+
288
+ @protected @Deprecated ('Prefer to use _setObjectData method, or operator [] for certain key.' )
289
+ void setObjectData (Map <String , dynamic > objectData) =>
290
+ _setObjectData (objectData);
224
291
}
0 commit comments