Skip to content

Commit 94d9f53

Browse files
yulingtianxiaphillwiggins
authored andcommitted
Support Relation. (parse-community#178)
* Added repo example * create CoreStore interface to allow different implements for local storage (parse-community#166) (parse-community#167) implement default local store using sembast and with encryption using XXTEA algorithm add desktop support in example project * Lint/Code clean * Some dart linter fixes (parse-community#171) * Support Relation. * delete vscode config * Update .gitignore
1 parent 5a18fa2 commit 94d9f53

36 files changed

+327
-190
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ build/
1010
.idea
1111
example/ios/Frameworks/
1212
example/lib/ui/
13+
14+
.vscode/

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
## 1.0.22
2+
13
## 1.0.21
24
LiveQuery fix
35
Logout fix

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Want to get involved? Join our Slack channel and help out! (http://flutter-parse
1313
To install, either add to your pubspec.yaml
1414
```yml
1515
dependencies:
16-
parse_server_sdk: ^1.0.21
16+
parse_server_sdk: ^1.0.22
1717
```
1818
or clone this repository and add to your project. As this is an early development with multiple contributors, it is probably best to download/clone and keep updating as an when a new feature is added.
1919
@@ -537,6 +537,21 @@ final Map<String, String> params = <String, String>{'plan': 'paid'};
537537
function.execute(parameters: params);
538538
```
539539

540+
## Relation
541+
The SDK supports Relation.
542+
543+
To Retrive a relation instance for user, call:
544+
```dart
545+
final relation = user.getRelation('dietPlans');
546+
```
547+
548+
and then you can add a relation to the passed in object.
549+
550+
```dart
551+
relation.add(dietPlan);
552+
final result = await user.save();
553+
```
554+
540555
## Other Features of this library
541556
Main:
542557
* Installation (View the example application)

example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@
4444
24DF2572E6AEEB9F7CE180C9 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
4545
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4646
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
47+
5804EFBD11740E02FC51BC3E /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
4748
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
4849
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
4950
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
51+
96499D95196B10F296043703 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
5052
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
5153
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
5254
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };

example/lib/data/repositories/user/provider_db_user.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class UserProviderDB implements UserProviderContract {
7979

8080
Map<String, dynamic> convertItemToStorageMap(User item) {
8181
final Map<String, dynamic> values = Map<String, dynamic>();
82+
// ignore: invalid_use_of_protected_member
8283
values['value'] = json.jsonEncode(item.toJson(full: true));
8384
values[keyVarObjectId] = item.objectId;
8485
item.updatedAt != null
@@ -90,8 +91,7 @@ class UserProviderDB implements UserProviderContract {
9091
User convertRecordToItem({Record record, Map<String, dynamic> values}) {
9192
try {
9293
values ??= record.value;
93-
final User item =
94-
User.clone().fromJson(json.jsonDecode(values['value']));
94+
final User item = User.clone().fromJson(json.jsonDecode(values['value']));
9595
return item;
9696
} catch (e) {
9797
return null;

example/lib/main.dart

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import 'package:flutter_plugin_example/data/repositories/diet_plan/repository_di
1010
import 'package:flutter_plugin_example/data/repositories/user/repository_user.dart';
1111
import 'package:flutter_plugin_example/domain/constants/application_constants.dart';
1212
import 'package:flutter_plugin_example/domain/utils/db_utils.dart';
13-
import 'package:flutter_plugin_example/pages/decision_page.dart';
1413
import 'package:flutter_stetho/flutter_stetho.dart';
1514
import 'package:parse_server_sdk/parse_server_sdk.dart';
1615

@@ -41,69 +40,74 @@ class MyApp extends StatefulWidget {
4140
class _MyAppState extends State<MyApp> {
4241
DietPlanRepository dietPlanRepo;
4342
UserRepository userRepo;
43+
44+
String text = '';
45+
4446
@override
4547
void initState() {
4648
super.initState();
47-
// initData();
49+
initData();
4850
}
4951

5052
@override
5153
Widget build(BuildContext context) {
5254
return MaterialApp(
53-
debugShowCheckedModeBanner: false,
54-
theme: ThemeData(
55-
primarySwatch: Colors.blue,
55+
home: Scaffold(
56+
appBar: AppBar(
57+
title: const Text('Plugin example app'),
58+
),
59+
body: Center(
60+
child: Text(text),
5661
),
57-
title: 'Parse Server Example',
58-
home: DecisionPage());
62+
),
63+
);
5964
}
6065

6166
Future<void> initData() async {
6267
// Initialize repository
63-
// await initRepository();
68+
await initRepository();
6469

6570
// Initialize parse
6671
Parse().initialize(keyParseApplicationId, keyParseServerUrl,
6772
masterKey: keyParseMasterKey, debug: true);
6873

69-
//parse serve with secure store and desktop support
70-
71-
// Parse().initialize(keyParseApplicationId, keyParseServerUrl,
72-
// masterKey: keyParseMasterKey,
73-
// debug: true,
74-
// coreStore: CoreStoreImp.getInstance());
75-
7674
// Check server is healthy and live - Debug is on in this instance so check logs for result
7775
final ParseResponse response = await Parse().healthCheck();
7876

7977
if (response.success) {
8078
await runTestQueries();
81-
print('runTestQueries');
79+
text += 'runTestQueries\n';
8280
} else {
81+
text += 'Server health check failed';
8382
print('Server health check failed');
8483
}
8584
}
8685

8786
Future<void> runTestQueries() async {
8887
// Basic repository example
89-
//await repositoryAddUser();
90-
//await repositoryAddItems();
91-
//await repositoryGetAllItems();
88+
await repositoryAddUser();
89+
await repositoryAddItems();
90+
await repositoryGetAllItems();
9291

9392
//Basic usage
94-
// createItem();
95-
// getAllItems();
96-
// getAllItemsByName();
97-
// getSingleItem();
98-
// getConfigs();
99-
// query();
100-
// initUser();
101-
// var instalattion = await ParseInstallation.currentInstallation();
102-
// var rees = instalattion.create();
103-
// print(rees);
104-
//function();
105-
//functionWithParameters();
106-
// test();
93+
await createItem();
94+
await getAllItems();
95+
await getAllItemsByName();
96+
await getSingleItem();
97+
await getConfigs();
98+
await query();
99+
await initUser();
100+
await initInstallation();
101+
await function();
102+
await functionWithParameters();
103+
await test();
104+
}
105+
106+
Future<void> initInstallation() async {
107+
final ParseInstallation installation =
108+
await ParseInstallation.currentInstallation();
109+
final ParseResponse response = await installation.create();
110+
print(response);
107111
}
108112

109113
Future<void> test() async {
@@ -359,13 +363,13 @@ class _MyAppState extends State<MyApp> {
359363
dietPlanRepo ??= DietPlanRepository.init(await getDB());
360364
userRepo ??= UserRepository.init(await getDB());
361365
}
362-
363-
String dietPlansToAdd =
364-
'[{"className":"Diet_Plans","Name":"Textbook","Description":"For an active lifestyle and a straight forward macro plan, we suggest this plan.","Fat":25,"Carbs":50,"Protein":25,"Status":0},'
365-
'{"className":"Diet_Plans","Name":"Body Builder","Description":"Default Body Builders Diet","Fat":20,"Carbs":40,"Protein":40,"Status":0},'
366-
'{"className":"Diet_Plans","Name":"Zone Diet","Description":"Popular with CrossFit users. Zone Diet targets similar macros.","Fat":30,"Carbs":40,"Protein":30,"Status":0},'
367-
'{"className":"Diet_Plans","Name":"Low Fat","Description":"Low fat diet.","Fat":15,"Carbs":60,"Protein":25,"Status":0},'
368-
'{"className":"Diet_Plans","Name":"Low Carb","Description":"Low Carb diet, main focus on quality fats and protein.","Fat":35,"Carbs":25,"Protein":40,"Status":0},'
369-
'{"className":"Diet_Plans","Name":"Paleo","Description":"Paleo diet.","Fat":60,"Carbs":25,"Protein":10,"Status":0},'
370-
'{"className":"Diet_Plans","Name":"Ketogenic","Description":"High quality fats, low carbs.","Fat":65,"Carbs":5,"Protein":30,"Status":0}]';
371366
}
367+
368+
const String dietPlansToAdd =
369+
'[{"className":"Diet_Plans","Name":"Textbook","Description":"For an active lifestyle and a straight forward macro plan, we suggest this plan.","Fat":25,"Carbs":50,"Protein":25,"Status":0},'
370+
'{"className":"Diet_Plans","Name":"Body Builder","Description":"Default Body Builders Diet","Fat":20,"Carbs":40,"Protein":40,"Status":0},'
371+
'{"className":"Diet_Plans","Name":"Zone Diet","Description":"Popular with CrossFit users. Zone Diet targets similar macros.","Fat":30,"Carbs":40,"Protein":30,"Status":0},'
372+
'{"className":"Diet_Plans","Name":"Low Fat","Description":"Low fat diet.","Fat":15,"Carbs":60,"Protein":25,"Status":0},'
373+
'{"className":"Diet_Plans","Name":"Low Carb","Description":"Low Carb diet, main focus on quality fats and protein.","Fat":35,"Carbs":25,"Protein":40,"Status":0},'
374+
'{"className":"Diet_Plans","Name":"Paleo","Description":"Paleo diet.","Fat":60,"Carbs":25,"Protein":10,"Status":0},'
375+
'{"className":"Diet_Plans","Name":"Ketogenic","Description":"High quality fats, low carbs.","Fat":65,"Carbs":5,"Protein":30,"Status":0}]';

example/windows/find_vcvars.dart

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@
1717
import 'dart:io';
1818

1919
int main() {
20-
final programDir = Platform.environment['PROGRAMFILES(X86)'];
21-
final pathPrefix = '$programDir\\Microsoft Visual Studio';
22-
const pathSuffix = 'VC\\Auxiliary\\Build\\vcvars64.bat';
23-
final years = ['2017', '2019'];
24-
final flavors = ['Community', 'Professional', 'Enterprise', 'Preview'];
25-
for (final year in years) {
26-
for (final flavor in flavors) {
27-
final testPath = '$pathPrefix\\$year\\$flavor\\$pathSuffix';
20+
final String programDir = Platform.environment['PROGRAMFILES(X86)'];
21+
final String pathPrefix = '$programDir\\Microsoft Visual Studio';
22+
const String pathSuffix = 'VC\\Auxiliary\\Build\\vcvars64.bat';
23+
final List<String> years = <String>['2017', '2019'];
24+
final List<String> flavors = <String>[
25+
'Community', 'Professional', 'Enterprise', 'Preview'];
26+
for (final String year in years) {
27+
for (final String flavor in flavors) {
28+
final String testPath = '$pathPrefix\\$year\\$flavor\\$pathSuffix';
2829
if (File(testPath).existsSync()) {
2930
print(testPath);
3031
return 0;

example/windows/generate_props.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
import 'dart:io';
1919

2020
void main(List<String> arguments) {
21-
final outputPath = arguments[0];
22-
final settings = {
21+
final String outputPath = arguments[0];
22+
final Map<String, String> settings = <String, String>{
2323
'FLUTTER_ROOT': arguments[1],
2424
'EXTRA_BUNDLE_FLAGS': arguments[2],
2525
};
@@ -39,16 +39,16 @@ ${getItemGroupContent(settings)}
3939
}
4040

4141
String getUserMacrosContent(Map<String, String> settings) {
42-
final macroList = StringBuffer();
43-
for (final setting in settings.entries) {
42+
final StringBuffer macroList = StringBuffer();
43+
for (final MapEntry<dynamic, dynamic> setting in settings.entries) {
4444
macroList.writeln(' <${setting.key}>${setting.value}</${setting.key}>');
4545
}
4646
return macroList.toString();
4747
}
4848

4949
String getItemGroupContent(Map<String, String> settings) {
50-
final macroList = StringBuffer();
51-
for (final name in settings.keys) {
50+
final StringBuffer macroList = StringBuffer();
51+
for (final String name in settings.keys) {
5252
macroList.writeln(''' <BuildMacro Include="$name">
5353
<Value>\$($name)</Value>
5454
<EnvironmentVariable>true</EnvironmentVariable>

lib/generated/i18n.dart

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import 'dart:async';
32

43
import 'package:flutter/foundation.dart';
@@ -13,35 +12,32 @@ class S implements WidgetsLocalizations {
1312
const S();
1413

1514
static const GeneratedLocalizationsDelegate delegate =
16-
const GeneratedLocalizationsDelegate();
15+
GeneratedLocalizationsDelegate();
1716

1817
static S of(BuildContext context) =>
1918
Localizations.of<S>(context, WidgetsLocalizations);
2019

2120
@override
2221
TextDirection get textDirection => TextDirection.ltr;
23-
2422
}
2523

2624
class en extends S {
2725
const en();
2826
}
2927

30-
31-
class GeneratedLocalizationsDelegate extends LocalizationsDelegate<WidgetsLocalizations> {
28+
class GeneratedLocalizationsDelegate
29+
extends LocalizationsDelegate<WidgetsLocalizations> {
3230
const GeneratedLocalizationsDelegate();
3331

3432
List<Locale> get supportedLocales {
3533
return const <Locale>[
36-
37-
const Locale("en", ""),
38-
34+
Locale("en", ""),
3935
];
4036
}
4137

4238
LocaleResolutionCallback resolution({Locale fallback}) {
4339
return (Locale locale, Iterable<Locale> supported) {
44-
final Locale languageLocale = new Locale(locale.languageCode, "");
40+
final Locale languageLocale = Locale(locale.languageCode, "");
4541
if (supported.contains(locale))
4642
return locale;
4743
else if (supported.contains(languageLocale))
@@ -57,12 +53,11 @@ class GeneratedLocalizationsDelegate extends LocalizationsDelegate<WidgetsLocali
5753
Future<WidgetsLocalizations> load(Locale locale) {
5854
final String lang = getLang(locale);
5955
switch (lang) {
60-
6156
case "en":
62-
return new SynchronousFuture<WidgetsLocalizations>(const en());
57+
return SynchronousFuture<WidgetsLocalizations>(const en());
6358

6459
default:
65-
return new SynchronousFuture<WidgetsLocalizations>(const S());
60+
return SynchronousFuture<WidgetsLocalizations>(const S());
6661
}
6762
}
6863

0 commit comments

Comments
 (0)