-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(datastore): implement ModelIndex #1366
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
import 'dart:convert'; | ||
|
||
import 'package:amplify_core/amplify_core.dart'; | ||
import 'package:collection/collection.dart'; | ||
import 'package:flutter/material.dart'; | ||
|
||
/// {@template model_index} | ||
/// Describes an index that is created by `@primaryKey` or `@index` directive, | ||
/// and is listed in [ModelSchemaDefinition.indexes]. | ||
/// {@endtemplate} | ||
@immutable | ||
class ModelIndex { | ||
/// Index name that is defined by the name parameter of `@index` directive in | ||
/// a model schema. [name] will always be null when the index is representing | ||
/// `@primaryKey` directive. | ||
final String? name; | ||
|
||
/// An array of field names. The first field is always the field that is | ||
/// annotated by` @primaryKey` or `@index` directive, and the remaining | ||
/// fields are the fields specified by `sortKeyFields` parameter of | ||
/// `@primaryKey` or `@index` directive. | ||
final List<String> fields; | ||
|
||
/// {@macro model_index} | ||
const ModelIndex({ | ||
required this.fields, | ||
this.name, | ||
}); | ||
|
||
/// Make a copy of an existing [ModelIndex] instance. | ||
ModelIndex copyWith({ | ||
List<String>? fields, | ||
String? name, | ||
}) => | ||
ModelIndex(fields: fields ?? this.fields, name: name ?? this.name); | ||
|
||
/// Generate a [Map] that represents [ModelIndex]. | ||
Map<String, dynamic> toMap() { | ||
final map = { | ||
'name': name, | ||
'fields': fields, | ||
}; | ||
|
||
return map; | ||
} | ||
|
||
/// Create an instance of [ModelIndex] from a [Map]. | ||
factory ModelIndex.fromMap(Map<String, dynamic> map) => | ||
ModelIndex(fields: map['fields'], name: map['name']); | ||
|
||
/// Create an instance of [ModelIndex] from a json | ||
factory ModelIndex.fromJson(String source) => | ||
ModelIndex.fromMap(jsonDecode(source)); | ||
|
||
/// Generate a json string that represents [ModelIndex] | ||
String toJson() => jsonEncode(toMap()); | ||
|
||
@override | ||
String toString() => 'ModelIndex(name: $name, fields: $fields)'; | ||
|
||
@override | ||
bool operator ==(Object other) { | ||
if (identical(this, other)) { | ||
return true; | ||
} | ||
|
||
final listEquals = const DeepCollectionEquality().equals; | ||
|
||
return other is ModelIndex && | ||
name == other.name && | ||
listEquals(fields, other.fields); | ||
} | ||
|
||
@override | ||
int get hashCode => name.hashCode ^ fields.hashCode; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,100 +1,109 @@ | ||
/* | ||
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
library model_schema; | ||
|
||
import 'dart:convert'; | ||
|
||
import 'package:collection/collection.dart'; | ||
|
||
import 'auth_rule.dart'; | ||
import 'model_field.dart'; | ||
|
||
class ModelSchema { | ||
final String name; | ||
final String? pluralName; //opt | ||
final List<AuthRule>? authRules; //opt | ||
final Map<String, ModelField>? fields; | ||
|
||
const ModelSchema({ | ||
required this.name, | ||
this.pluralName, | ||
this.authRules, | ||
this.fields, | ||
}); | ||
|
||
ModelSchema copyWith( | ||
{String? name, | ||
String? pluralName, | ||
List<AuthRule>? authRules, | ||
Map<String, ModelField>? fields}) { | ||
return ModelSchema( | ||
name: name ?? this.name, | ||
pluralName: pluralName ?? this.pluralName, | ||
authRules: authRules ?? this.authRules, | ||
fields: fields ?? this.fields); | ||
} | ||
|
||
Map<String, dynamic> toMap() { | ||
final map = { | ||
'name': name, | ||
'pluralName': pluralName, | ||
'authRules': authRules?.map((x) => x.toMap()).toList(), | ||
'fields': fields?.map((key, value) => MapEntry('$key', value.toMap())), | ||
}; | ||
return Map<String, dynamic>.from(map) | ||
..removeWhere((k, dynamic v) => v == null); | ||
} | ||
|
||
factory ModelSchema.fromMap(Map<String, dynamic> map) { | ||
return ModelSchema( | ||
name: map['name'], | ||
pluralName: map['pluralName'], | ||
authRules: List<AuthRule>.from( | ||
map['authRules']?.map((dynamic x) => AuthRule.fromMap(x))), | ||
fields: Map<String, ModelField>.from(map['fields']), | ||
); | ||
} | ||
|
||
String toJson() => json.encode(toMap()); | ||
|
||
factory ModelSchema.fromJson(String source) => | ||
ModelSchema.fromMap(json.decode(source)); | ||
|
||
@override | ||
String toString() { | ||
return 'ModelSchema(name: $name, pluralName: $pluralName, authRules: $authRules, fields: $fields)'; | ||
} | ||
|
||
@override | ||
bool operator ==(Object o) { | ||
if (identical(this, o)) return true; | ||
final collectionEquals = const DeepCollectionEquality().equals; | ||
|
||
return o is ModelSchema && | ||
o.name == name && | ||
o.pluralName == pluralName && | ||
collectionEquals(o.authRules, authRules) && | ||
collectionEquals(o.fields, fields); | ||
} | ||
|
||
@override | ||
int get hashCode { | ||
return name.hashCode ^ | ||
pluralName.hashCode ^ | ||
authRules.hashCode ^ | ||
fields.hashCode; | ||
} | ||
} | ||
/* | ||
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why this is registering as a change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As this PR converts this file from CRLF to LF mode (The first commit of this PR). |
||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
library model_schema; | ||
|
||
import 'dart:convert'; | ||
|
||
import 'package:collection/collection.dart'; | ||
|
||
import 'auth_rule.dart'; | ||
import 'model_field.dart'; | ||
import 'model_index.dart'; | ||
|
||
class ModelSchema { | ||
final String name; | ||
final String? pluralName; //opt | ||
final List<AuthRule>? authRules; //opt | ||
final Map<String, ModelField>? fields; | ||
final List<ModelIndex>? indexes; | ||
|
||
const ModelSchema({ | ||
required this.name, | ||
this.pluralName, | ||
this.authRules, | ||
this.fields, | ||
this.indexes, | ||
}); | ||
|
||
ModelSchema copyWith( | ||
{String? name, | ||
String? pluralName, | ||
List<AuthRule>? authRules, | ||
Map<String, ModelField>? fields}) { | ||
return ModelSchema( | ||
name: name ?? this.name, | ||
pluralName: pluralName ?? this.pluralName, | ||
authRules: authRules ?? this.authRules, | ||
fields: fields ?? this.fields, | ||
indexes: indexes ?? this.indexes, | ||
); | ||
} | ||
|
||
Map<String, dynamic> toMap() { | ||
final map = { | ||
'name': name, | ||
'pluralName': pluralName, | ||
'authRules': authRules?.map((x) => x.toMap()).toList(), | ||
'fields': fields?.map((key, value) => MapEntry('$key', value.toMap())), | ||
'indexes': indexes?.map((value) => value.toMap()).toList(), | ||
}; | ||
return Map<String, dynamic>.from(map) | ||
..removeWhere((k, dynamic v) => v == null); | ||
} | ||
|
||
factory ModelSchema.fromMap(Map<String, dynamic> map) { | ||
return ModelSchema( | ||
name: map['name'], | ||
pluralName: map['pluralName'], | ||
authRules: List<AuthRule>.from( | ||
map['authRules']?.map((dynamic x) => AuthRule.fromMap(x))), | ||
fields: Map<String, ModelField>.from(map['fields']), | ||
indexes: List<ModelIndex>.from(map['indexes']), | ||
); | ||
} | ||
|
||
String toJson() => json.encode(toMap()); | ||
|
||
factory ModelSchema.fromJson(String source) => | ||
ModelSchema.fromMap(json.decode(source)); | ||
|
||
@override | ||
String toString() { | ||
return 'ModelSchema(name: $name, pluralName: $pluralName, authRules: $authRules, fields: $fields, indexes: $indexes)'; | ||
} | ||
|
||
@override | ||
bool operator ==(Object o) { | ||
if (identical(this, o)) return true; | ||
final collectionEquals = const DeepCollectionEquality().equals; | ||
|
||
return o is ModelSchema && | ||
o.name == name && | ||
o.pluralName == pluralName && | ||
collectionEquals(o.authRules, authRules) && | ||
collectionEquals(o.fields, fields) && | ||
collectionEquals(o.indexes, indexes); | ||
} | ||
|
||
@override | ||
int get hashCode { | ||
return name.hashCode ^ | ||
pluralName.hashCode ^ | ||
authRules.hashCode ^ | ||
fields.hashCode ^ | ||
indexes.hashCode; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we start using the
AWSEquatable
mixin instead of implementing these everywhere? It is currently in amplify_flutter, so you would have to move it if you want to use it. I don't think you have to use it for this PR, but I want to discuss if we want to start using it moving forward.@dnys1 I think you added AWSEquatable. Any reason we can't move that to amplify_core and start using it throughout all packages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, wasn't aware of this mixin. Can we also use it with generated models? @dnys1