Add ISSUE_TEMPLATE
This commit is contained in:
parent
13a693a54c
commit
b0df26f3dd
80 changed files with 160 additions and 4441 deletions
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: ⚠️ Extension Issue
|
||||
url: https://github.com/kodjodevf/mangayomi-extensions/issues/new
|
||||
about: Issues and requests for extensions and sources should be opened in the mangayomi-extensions repository instead
|
||||
- name: 🧑💻 Mangayomi help discord
|
||||
url: https://discord.com/invite/EjfBuYahsP
|
||||
about: Common questions are answered here
|
||||
80
.github/ISSUE_TEMPLATE/report_issue.yml
vendored
Normal file
80
.github/ISSUE_TEMPLATE/report_issue.yml
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
name: 🐞 Issue report
|
||||
description: Report an issue in Mangayomi
|
||||
labels: [Bug]
|
||||
body:
|
||||
- type: textarea
|
||||
id: reproduce-steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Provide an example of the issue.
|
||||
placeholder: |
|
||||
Example:
|
||||
1. First step
|
||||
2. Second step
|
||||
3. Issue here
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: Explain what you should expect to happen.
|
||||
placeholder: |
|
||||
Example:
|
||||
"This should happen..."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: actual-behavior
|
||||
attributes:
|
||||
label: Actual behavior
|
||||
description: Explain what actually happens.
|
||||
placeholder: |
|
||||
Example:
|
||||
"This happened instead..."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: mangayomi-version
|
||||
attributes:
|
||||
label: Mangayomi version
|
||||
description: You can find your Mangayomi version in **More → About**.
|
||||
placeholder: |
|
||||
Example: "0.0.67"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: device
|
||||
attributes:
|
||||
label: Device
|
||||
description: List your device, model and the OS version.
|
||||
placeholder: |
|
||||
Example: "Google Pixel 5 android 11"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: other-details
|
||||
attributes:
|
||||
label: Other details
|
||||
placeholder: |
|
||||
Additional details and attachments.
|
||||
|
||||
- type: checkboxes
|
||||
id: acknowledgements
|
||||
attributes:
|
||||
label: Acknowledgements
|
||||
description: Read this carefully, we will close and ignore your issue if you skimmed through this.
|
||||
options:
|
||||
- label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open or closed issue.
|
||||
required: true
|
||||
- label: I have written a short but informative title.
|
||||
required: true
|
||||
- label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/kodjodevf/mangayomi-extensions/issues/new).
|
||||
required: true
|
||||
- label: I have updated all installed extensions.
|
||||
required: true
|
||||
32
.github/ISSUE_TEMPLATE/request_feature.yml
vendored
Normal file
32
.github/ISSUE_TEMPLATE/request_feature.yml
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
name: ⭐ Feature request
|
||||
description: Suggest a feature to improve Mangayomi
|
||||
labels: [Feature request]
|
||||
body:
|
||||
- type: textarea
|
||||
id: feature-description
|
||||
attributes:
|
||||
label: Describe your suggested feature
|
||||
description: How can Mangayomi be improved?
|
||||
placeholder: |
|
||||
Example:
|
||||
"It should work like this..."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: other-details
|
||||
attributes:
|
||||
label: Other details
|
||||
placeholder: |
|
||||
Additional details and attachments.
|
||||
|
||||
- type: checkboxes
|
||||
id: acknowledgements
|
||||
attributes:
|
||||
label: Acknowledgements
|
||||
description: Read this carefully, we will close and ignore your issue if you skimmed through this.
|
||||
options:
|
||||
- label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open or closed issue.
|
||||
required: true
|
||||
- label: I have written a short but informative title.
|
||||
required: true
|
||||
30
.metadata
30
.metadata
|
|
@ -1,30 +0,0 @@
|
|||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled.
|
||||
|
||||
version:
|
||||
revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
|
||||
channel: stable
|
||||
|
||||
project_type: app
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
|
||||
base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
|
||||
- platform: macos
|
||||
create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
|
||||
base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
|
||||
|
||||
# User provided section
|
||||
|
||||
# List of Local paths (relative to this file) that should be
|
||||
# ignored by the migrate tool.
|
||||
#
|
||||
# Files that are not part of the templates will be ignored by default.
|
||||
unmanaged_files:
|
||||
- 'lib/main.dart'
|
||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||
|
|
@ -99,58 +99,39 @@ class MainScreen extends ConsumerWidget {
|
|||
useIndicator: true,
|
||||
destinations: [
|
||||
NavigationRailDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.collections_bookmark,
|
||||
),
|
||||
selectedIcon:
|
||||
const Icon(Icons.collections_bookmark),
|
||||
icon: const Icon(
|
||||
Icons.collections_bookmark_outlined,
|
||||
),
|
||||
Icons.collections_bookmark_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.manga))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.video_collection,
|
||||
),
|
||||
selectedIcon:
|
||||
const Icon(Icons.video_collection),
|
||||
icon: const Icon(
|
||||
Icons.video_collection_outlined,
|
||||
),
|
||||
Icons.video_collection_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.anime),
|
||||
)),
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.anime))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.new_releases,
|
||||
),
|
||||
icon: const Icon(
|
||||
Icons.new_releases_outlined,
|
||||
),
|
||||
selectedIcon: const Icon(Icons.history),
|
||||
icon: const Icon(Icons.history_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.history))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.history,
|
||||
),
|
||||
icon: const Icon(
|
||||
Icons.history_outlined,
|
||||
),
|
||||
selectedIcon: const Icon(Icons.explore),
|
||||
icon: const Icon(Icons.explore_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.browse),
|
||||
)),
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.browse))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.more_horiz,
|
||||
),
|
||||
icon: const Icon(
|
||||
Icons.more_horiz_outlined,
|
||||
),
|
||||
selectedIcon: const Icon(Icons.more_horiz),
|
||||
icon: const Icon(Icons.more_horiz_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.more),
|
||||
)),
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.more))),
|
||||
],
|
||||
selectedIndex: currentIndex,
|
||||
onDestinationSelected: (newIndex) {
|
||||
|
|
@ -201,44 +182,28 @@ class MainScreen extends ConsumerWidget {
|
|||
selectedIndex: currentIndex,
|
||||
destinations: [
|
||||
NavigationDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.collections_bookmark,
|
||||
),
|
||||
selectedIcon:
|
||||
const Icon(Icons.collections_bookmark),
|
||||
icon: const Icon(
|
||||
Icons.collections_bookmark_outlined,
|
||||
),
|
||||
Icons.collections_bookmark_outlined),
|
||||
label: l10n.manga),
|
||||
NavigationDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.video_collection,
|
||||
),
|
||||
icon: const Icon(
|
||||
Icons.video_collection_outlined,
|
||||
),
|
||||
selectedIcon:
|
||||
const Icon(Icons.video_collection),
|
||||
icon:
|
||||
const Icon(Icons.video_collection_outlined),
|
||||
label: l10n.anime),
|
||||
NavigationDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.new_releases,
|
||||
),
|
||||
icon: const Icon(
|
||||
Icons.new_releases_outlined,
|
||||
),
|
||||
selectedIcon: const Icon(Icons.history),
|
||||
icon: const Icon(Icons.history_outlined),
|
||||
label: l10n.history),
|
||||
NavigationDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.history,
|
||||
),
|
||||
icon: const Icon(
|
||||
Icons.history_outlined,
|
||||
),
|
||||
selectedIcon: const Icon(Icons.explore),
|
||||
icon: const Icon(Icons.explore_outlined),
|
||||
label: l10n.browse),
|
||||
NavigationDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.more_horiz,
|
||||
),
|
||||
icon: const Icon(
|
||||
Icons.more_horiz_outlined,
|
||||
),
|
||||
selectedIcon: const Icon(Icons.more_horiz),
|
||||
icon: const Icon(Icons.more_horiz_outlined),
|
||||
label: l10n.more),
|
||||
],
|
||||
onDestinationSelected: (newIndex) {
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
See [Isar Changelog](https://pub.dev/packages/isar/changelog)
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License 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.
|
||||
|
|
@ -1 +0,0 @@
|
|||
### Code generator for the [Isar Database](https://github.com/isar/isar) please go there for documentation.
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
include: package:very_good_analysis/analysis_options.yaml
|
||||
|
||||
analyzer:
|
||||
errors:
|
||||
cascade_invocations: ignore
|
||||
avoid_positional_boolean_parameters: ignore
|
||||
parameter_assignments: ignore
|
||||
public_member_api_docs: ignore
|
||||
use_string_buffers: ignore
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
builders:
|
||||
isar_generator:
|
||||
import: "package:isar_generator/isar_generator.dart"
|
||||
builder_factories: ["getIsarGenerator"]
|
||||
build_extensions: { ".dart": ["isar_generator.g.part"] }
|
||||
auto_apply: dependents
|
||||
build_to: cache
|
||||
applies_builders: ["source_gen|combining_builder"]
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import 'package:build/build.dart';
|
||||
import 'package:isar_generator/src/collection_generator.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
Builder getIsarGenerator(BuilderOptions options) => SharedPartBuilder(
|
||||
[
|
||||
IsarCollectionGenerator(),
|
||||
IsarEmbeddedGenerator(),
|
||||
],
|
||||
'isar_generator',
|
||||
);
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar_generator/src/object_info.dart';
|
||||
|
||||
String generateByIndexExtension(ObjectInfo oi) {
|
||||
final uniqueIndexes = oi.indexes.where((e) => e.unique).toList();
|
||||
if (uniqueIndexes.isEmpty) {
|
||||
return '';
|
||||
}
|
||||
var code =
|
||||
'extension ${oi.dartName}ByIndex on IsarCollection<${oi.dartName}> {';
|
||||
for (final index in uniqueIndexes) {
|
||||
code += generateSingleByIndex(oi, index);
|
||||
code += generateAllByIndex(oi, index);
|
||||
if (!index.properties.first.isMultiEntry) {
|
||||
code += generatePutByIndex(oi, index);
|
||||
}
|
||||
}
|
||||
return '''
|
||||
$code
|
||||
}''';
|
||||
}
|
||||
|
||||
extension on ObjectIndex {
|
||||
String get dartName {
|
||||
return properties.map((e) => e.property.dartName.capitalize()).join();
|
||||
}
|
||||
}
|
||||
|
||||
String generateSingleByIndex(ObjectInfo oi, ObjectIndex index) {
|
||||
final params = index.properties
|
||||
.map((i) => '${i.property.dartType} ${i.property.dartName}')
|
||||
.join(',');
|
||||
final paramsList = index.properties.map((i) => i.property.dartName).join(',');
|
||||
return '''
|
||||
Future<${oi.dartName}?> getBy${index.dartName}($params) {
|
||||
return getByIndex(r'${index.name}', [$paramsList]);
|
||||
}
|
||||
|
||||
${oi.dartName}? getBy${index.dartName}Sync($params) {
|
||||
return getByIndexSync(r'${index.name}', [$paramsList]);
|
||||
}
|
||||
|
||||
Future<bool> deleteBy${index.dartName}($params) {
|
||||
return deleteByIndex(r'${index.name}', [$paramsList]);
|
||||
}
|
||||
|
||||
bool deleteBy${index.dartName}Sync($params) {
|
||||
return deleteByIndexSync(r'${index.name}', [$paramsList]);
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateAllByIndex(ObjectInfo oi, ObjectIndex index) {
|
||||
String valsName(ObjectProperty p) => '${p.dartName}Values';
|
||||
|
||||
final props = index.properties;
|
||||
final params = props
|
||||
.map((ip) => 'List<${ip.property.dartType}> ${valsName(ip.property)}')
|
||||
.join(',');
|
||||
String createValues;
|
||||
if (props.length == 1) {
|
||||
final p = props.first.property;
|
||||
createValues = 'final values = ${valsName(p)}.map((e) => [e]).toList();';
|
||||
} else {
|
||||
final lenAssert = props
|
||||
.sublist(1)
|
||||
.map((i) => '${valsName(i.property)}.length == len')
|
||||
.join('&&');
|
||||
createValues = '''
|
||||
final len = ${valsName(props.first.property)}.length;
|
||||
assert($lenAssert, 'All index values must have the same length');
|
||||
final values = <List<dynamic>>[];
|
||||
for (var i = 0; i < len; i++) {
|
||||
values.add([${props.map((ip) => '${valsName(ip.property)}[i]').join(',')}]);
|
||||
}
|
||||
''';
|
||||
}
|
||||
return '''
|
||||
Future<List<${oi.dartName}?>> getAllBy${index.dartName}($params) {
|
||||
$createValues
|
||||
return getAllByIndex(r'${index.name}', values);
|
||||
}
|
||||
|
||||
List<${oi.dartName}?> getAllBy${index.dartName}Sync($params) {
|
||||
$createValues
|
||||
return getAllByIndexSync(r'${index.name}', values);
|
||||
}
|
||||
|
||||
Future<int> deleteAllBy${index.dartName}($params) {
|
||||
$createValues
|
||||
return deleteAllByIndex(r'${index.name}', values);
|
||||
}
|
||||
|
||||
int deleteAllBy${index.dartName}Sync($params) {
|
||||
$createValues
|
||||
return deleteAllByIndexSync(r'${index.name}', values);
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generatePutByIndex(ObjectInfo oi, ObjectIndex index) {
|
||||
return '''
|
||||
Future<Id> putBy${index.dartName}(${oi.dartName} object) {
|
||||
return putByIndex(r'${index.name}', object);
|
||||
}
|
||||
|
||||
Id putBy${index.dartName}Sync(${oi.dartName} object, {bool saveLinks = true}) {
|
||||
return putByIndexSync(r'${index.name}', object, saveLinks: saveLinks);
|
||||
}
|
||||
|
||||
Future<List<Id>> putAllBy${index.dartName}(List<${oi.dartName}> objects) {
|
||||
return putAllByIndex(r'${index.name}', objects);
|
||||
}
|
||||
|
||||
List<Id> putAllBy${index.dartName}Sync(List<${oi.dartName}> objects, {bool saveLinks = true}) {
|
||||
return putAllByIndexSync(r'${index.name}', objects, saveLinks: saveLinks);
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:isar_generator/src/isar_type.dart';
|
||||
|
||||
import 'package:isar_generator/src/object_info.dart';
|
||||
|
||||
String generateSchema(ObjectInfo object) {
|
||||
var code = 'const ${object.dartName.capitalize()}Schema = ';
|
||||
if (!object.isEmbedded) {
|
||||
code += 'CollectionSchema(';
|
||||
} else {
|
||||
code += 'Schema(';
|
||||
}
|
||||
|
||||
final properties = object.objectProperties
|
||||
.mapIndexed(
|
||||
(i, e) => "r'${e.isarName}': ${_generatePropertySchema(object, i)}",
|
||||
)
|
||||
.join(',');
|
||||
|
||||
code += '''
|
||||
name: r'${object.isarName}',
|
||||
id: ${object.id},
|
||||
properties: {$properties},
|
||||
|
||||
estimateSize: ${object.estimateSizeName},
|
||||
serialize: ${object.serializeName},
|
||||
deserialize: ${object.deserializeName},
|
||||
deserializeProp: ${object.deserializePropName},''';
|
||||
|
||||
if (!object.isEmbedded) {
|
||||
final indexes = object.indexes
|
||||
.map((e) => "r'${e.name}': ${_generateIndexSchema(e)}")
|
||||
.join(',');
|
||||
final links = object.links
|
||||
.map((e) => "r'${e.isarName}': ${_generateLinkSchema(object, e)}")
|
||||
.join(',');
|
||||
final embeddedSchemas = object.embeddedDartNames.entries
|
||||
.map((e) => "r'${e.key}': ${e.value.capitalize()}Schema")
|
||||
.join(',');
|
||||
|
||||
code += '''
|
||||
idName: r'${object.idProperty.isarName}',
|
||||
indexes: {$indexes},
|
||||
links: {$links},
|
||||
embeddedSchemas: {$embeddedSchemas},
|
||||
|
||||
getId: ${object.getIdName},
|
||||
getLinks: ${object.getLinksName},
|
||||
attach: ${object.attachName},
|
||||
version: '${Isar.version}',
|
||||
''';
|
||||
}
|
||||
|
||||
return '$code);';
|
||||
}
|
||||
|
||||
String _generatePropertySchema(ObjectInfo object, int index) {
|
||||
final property = object.objectProperties[index];
|
||||
var enumMap = '';
|
||||
if (property.isEnum) {
|
||||
enumMap = 'enumMap: ${property.enumValueMapName(object)},';
|
||||
}
|
||||
var target = '';
|
||||
if (property.targetIsarName != null) {
|
||||
target = "target: r'${property.targetIsarName}',";
|
||||
}
|
||||
return '''
|
||||
PropertySchema(
|
||||
id: $index,
|
||||
name: r'${property.isarName}',
|
||||
type: IsarType.${property.isarType.name},
|
||||
$enumMap
|
||||
$target
|
||||
)
|
||||
''';
|
||||
}
|
||||
|
||||
String _generateIndexSchema(ObjectIndex index) {
|
||||
final properties = index.properties.map((e) {
|
||||
return '''
|
||||
IndexPropertySchema(
|
||||
name: r'${e.property.isarName}',
|
||||
type: IndexType.${e.type.name},
|
||||
caseSensitive: ${e.caseSensitive},
|
||||
)''';
|
||||
}).join(',');
|
||||
|
||||
return '''
|
||||
IndexSchema(
|
||||
id: ${index.id},
|
||||
name: r'${index.name}',
|
||||
unique: ${index.unique},
|
||||
replace: ${index.replace},
|
||||
properties: [$properties],
|
||||
)''';
|
||||
}
|
||||
|
||||
String _generateLinkSchema(ObjectInfo object, ObjectLink link) {
|
||||
var linkName = '';
|
||||
if (link.isBacklink) {
|
||||
linkName = "linkName: r'${link.targetLinkIsarName}',";
|
||||
}
|
||||
return '''
|
||||
LinkSchema(
|
||||
id: ${link.id(object.isarName)},
|
||||
name: r'${link.isarName}',
|
||||
target: r'${link.targetCollectionIsarName}',
|
||||
single: ${link.isSingle},
|
||||
$linkName
|
||||
)''';
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:isar_generator/src/isar_type.dart';
|
||||
import 'package:isar_generator/src/object_info.dart';
|
||||
|
||||
String generateDistinctBy(ObjectInfo oi) {
|
||||
var code = '''
|
||||
extension ${oi.dartName}QueryWhereDistinct on QueryBuilder<${oi.dartName}, ${oi.dartName}, QDistinct> {''';
|
||||
for (final property in oi.objectProperties) {
|
||||
if (property.isarType == IsarType.string) {
|
||||
code += '''
|
||||
QueryBuilder<${oi.dartName}, ${oi.dartName}, QDistinct>distinctBy${property.dartName.capitalize()}({bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'${property.isarName}', caseSensitive: caseSensitive);
|
||||
});
|
||||
}''';
|
||||
} else if (!property.isarType.containsObject) {
|
||||
code += '''
|
||||
QueryBuilder<${oi.dartName}, ${oi.dartName}, QDistinct>distinctBy${property.dartName.capitalize()}() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'${property.isarName}');
|
||||
});
|
||||
}''';
|
||||
}
|
||||
}
|
||||
return '$code}';
|
||||
}
|
||||
|
|
@ -1,278 +0,0 @@
|
|||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:isar_generator/src/code_gen/query_filter_length.dart';
|
||||
import 'package:isar_generator/src/isar_type.dart';
|
||||
import 'package:isar_generator/src/object_info.dart';
|
||||
|
||||
class FilterGenerator {
|
||||
FilterGenerator(this.object) : objName = object.dartName;
|
||||
final ObjectInfo object;
|
||||
final String objName;
|
||||
|
||||
String generate() {
|
||||
var code =
|
||||
'extension ${objName}QueryFilter on QueryBuilder<$objName, $objName, '
|
||||
'QFilterCondition> {';
|
||||
for (final property in object.properties) {
|
||||
if (property.nullable) {
|
||||
code += generateIsNull(property);
|
||||
code += generateIsNotNull(property);
|
||||
}
|
||||
if (property.elementNullable) {
|
||||
code += generateElementIsNull(property);
|
||||
code += generateElementIsNotNull(property);
|
||||
}
|
||||
|
||||
if (!property.isarType.containsObject) {
|
||||
code += generateEqualTo(property);
|
||||
|
||||
if (!property.isarType.containsBool) {
|
||||
code += generateGreaterThan(property);
|
||||
code += generateLessThan(property);
|
||||
code += generateBetween(property);
|
||||
}
|
||||
}
|
||||
|
||||
if (property.isarType.containsString) {
|
||||
code += generateStringStartsWith(property);
|
||||
code += generateStringEndsWith(property);
|
||||
code += generateStringContains(property);
|
||||
code += generateStringMatches(property);
|
||||
code += generateStringIsEmpty(property);
|
||||
code += generateStringIsNotEmpty(property);
|
||||
}
|
||||
|
||||
if (property.isarType.isList) {
|
||||
code += generateListLength(property);
|
||||
}
|
||||
}
|
||||
return '''
|
||||
$code
|
||||
}''';
|
||||
}
|
||||
|
||||
String mPrefix(ObjectProperty p, [bool listElement = true]) {
|
||||
final any = listElement && p.isarType.isList ? 'Element' : '';
|
||||
return 'QueryBuilder<$objName, $objName, QAfterFilterCondition> '
|
||||
'${p.dartName.decapitalize()}$any';
|
||||
}
|
||||
|
||||
String generateEqualTo(ObjectProperty p) {
|
||||
final optional = [
|
||||
if (p.isarType.containsString) 'bool caseSensitive = true',
|
||||
if (p.isarType.containsFloat) 'double epsilon = Query.epsilon',
|
||||
].join(',');
|
||||
return '''
|
||||
${mPrefix(p)}EqualTo(${p.nScalarDartType} value ${optional.isNotBlank ? ', {$optional,}' : ''}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'${p.isarName}',
|
||||
value: value,
|
||||
${p.isarType.containsString ? 'caseSensitive: caseSensitive,' : ''}
|
||||
${p.isarType.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateGreaterThan(ObjectProperty p) {
|
||||
final optional = [
|
||||
'bool include = false',
|
||||
if (p.isarType.containsString) 'bool caseSensitive = true',
|
||||
if (p.isarType.containsFloat) 'double epsilon = Query.epsilon',
|
||||
].join(',');
|
||||
return '''
|
||||
${mPrefix(p)}GreaterThan(${p.nScalarDartType} value, {$optional,}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
include: include,
|
||||
property: r'${p.isarName}',
|
||||
value: value,
|
||||
${p.isarType.containsString ? 'caseSensitive: caseSensitive,' : ''}
|
||||
${p.isarType.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateLessThan(ObjectProperty p) {
|
||||
final optional = [
|
||||
'bool include = false',
|
||||
if (p.isarType.containsString) 'bool caseSensitive = true',
|
||||
if (p.isarType.containsFloat) 'double epsilon = Query.epsilon',
|
||||
].join(',');
|
||||
return '''
|
||||
${mPrefix(p)}LessThan(${p.nScalarDartType} value, {$optional,}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.lessThan(
|
||||
include: include,
|
||||
property: r'${p.isarName}',
|
||||
value: value,
|
||||
${p.isarType.containsString ? 'caseSensitive: caseSensitive,' : ''}
|
||||
${p.isarType.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateBetween(ObjectProperty p) {
|
||||
final optional = [
|
||||
'bool includeLower = true',
|
||||
'bool includeUpper = true',
|
||||
if (p.isarType.containsString) 'bool caseSensitive = true',
|
||||
if (p.isarType.containsFloat) 'double epsilon = Query.epsilon',
|
||||
].join(',');
|
||||
return '''
|
||||
${mPrefix(p)}Between(${p.nScalarDartType} lower, ${p.nScalarDartType} upper, {$optional,}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.between(
|
||||
property: r'${p.isarName}',
|
||||
lower: lower,
|
||||
includeLower: includeLower,
|
||||
upper: upper,
|
||||
includeUpper: includeUpper,
|
||||
${p.isarType.containsString ? 'caseSensitive: caseSensitive,' : ''}
|
||||
${p.isarType.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateIsNull(ObjectProperty p) {
|
||||
return '''
|
||||
${mPrefix(p, false)}IsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
property: r'${p.isarName}',
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateElementIsNull(ObjectProperty p) {
|
||||
return '''
|
||||
${mPrefix(p)}IsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.elementIsNull(
|
||||
property: r'${p.isarName}',
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateIsNotNull(ObjectProperty p) {
|
||||
return '''
|
||||
${mPrefix(p, false)}IsNotNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query
|
||||
.addFilterCondition(const FilterCondition.isNotNull(
|
||||
property: r'${p.isarName}',
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateElementIsNotNull(ObjectProperty p) {
|
||||
return '''
|
||||
${mPrefix(p)}IsNotNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query
|
||||
.addFilterCondition(const FilterCondition.elementIsNotNull(
|
||||
property: r'${p.isarName}',
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateStringStartsWith(ObjectProperty p) {
|
||||
return '''
|
||||
${mPrefix(p)}StartsWith(String value, {bool caseSensitive = true,}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.startsWith(
|
||||
property: r'${p.isarName}',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateStringEndsWith(ObjectProperty p) {
|
||||
return '''
|
||||
${mPrefix(p)}EndsWith(String value, {bool caseSensitive = true,}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.endsWith(
|
||||
property: r'${p.isarName}',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateStringContains(ObjectProperty p) {
|
||||
return '''
|
||||
${mPrefix(p)}Contains(String value, {bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.contains(
|
||||
property: r'${p.isarName}',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateStringMatches(ObjectProperty p) {
|
||||
return '''
|
||||
${mPrefix(p)}Matches(String pattern, {bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.matches(
|
||||
property: r'${p.isarName}',
|
||||
wildcard: pattern,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateStringIsEmpty(ObjectProperty p) {
|
||||
return '''
|
||||
${mPrefix(p)}IsEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'${p.isarName}',
|
||||
value: '',
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateStringIsNotEmpty(ObjectProperty p) {
|
||||
return '''
|
||||
${mPrefix(p)}IsNotEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
property: r'${p.isarName}',
|
||||
value: '',
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateListLength(ObjectProperty p) {
|
||||
return generateLength(objName, p.dartName,
|
||||
(lower, includeLower, upper, includeUpper) {
|
||||
return '''
|
||||
QueryBuilder.apply(this, (query) {
|
||||
return query.listLength(
|
||||
r'${p.isarName}',
|
||||
$lower,
|
||||
$includeLower,
|
||||
$upper,
|
||||
$includeUpper,
|
||||
);
|
||||
})''';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
import 'package:dartx/dartx.dart';
|
||||
|
||||
String generateLength(
|
||||
String objectName,
|
||||
String propertyName,
|
||||
String Function(
|
||||
String lower,
|
||||
String includeLower,
|
||||
String upper,
|
||||
String includeUpper,
|
||||
)
|
||||
codeGen,
|
||||
) {
|
||||
return '''
|
||||
QueryBuilder<$objectName, $objectName, QAfterFilterCondition> ${propertyName.decapitalize()}LengthEqualTo(int length) {
|
||||
return ${codeGen('length', 'true', 'length', 'true')};
|
||||
}
|
||||
|
||||
QueryBuilder<$objectName, $objectName, QAfterFilterCondition> ${propertyName.decapitalize()}IsEmpty() {
|
||||
return ${codeGen('0', 'true', '0', 'true')};
|
||||
}
|
||||
|
||||
QueryBuilder<$objectName, $objectName, QAfterFilterCondition> ${propertyName.decapitalize()}IsNotEmpty() {
|
||||
return ${codeGen('0', 'false', '999999', 'true')};
|
||||
}
|
||||
|
||||
QueryBuilder<$objectName, $objectName, QAfterFilterCondition> ${propertyName.decapitalize()}LengthLessThan(
|
||||
int length, {
|
||||
bool include = false,
|
||||
}) {
|
||||
return ${codeGen('0', 'true', 'length', 'include')};
|
||||
}
|
||||
|
||||
QueryBuilder<$objectName, $objectName, QAfterFilterCondition> ${propertyName.decapitalize()}LengthGreaterThan(
|
||||
int length, {
|
||||
bool include = false,
|
||||
}) {
|
||||
return ${codeGen('length', 'include', '999999', 'true')};
|
||||
}
|
||||
|
||||
QueryBuilder<$objectName, $objectName, QAfterFilterCondition> ${propertyName.decapitalize()}LengthBetween(
|
||||
int lower,
|
||||
int upper, {
|
||||
bool includeLower = true,
|
||||
bool includeUpper = true,
|
||||
}) {
|
||||
return ${codeGen('lower', 'includeLower', 'upper', 'includeUpper')};
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar_generator/src/code_gen/query_filter_length.dart';
|
||||
import 'package:isar_generator/src/object_info.dart';
|
||||
|
||||
String generateQueryLinks(ObjectInfo oi) {
|
||||
var code =
|
||||
'extension ${oi.dartName}QueryLinks on QueryBuilder<${oi.dartName}, '
|
||||
'${oi.dartName}, QFilterCondition> {';
|
||||
for (final link in oi.links) {
|
||||
code += '''
|
||||
QueryBuilder<${oi.dartName}, ${oi.dartName}, QAfterFilterCondition> ${link.dartName.decapitalize()}(FilterQuery<${link.targetCollectionDartName}> q) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.link(q, r'${link.isarName}');
|
||||
});
|
||||
}''';
|
||||
|
||||
if (link.isSingle) {
|
||||
code += '''
|
||||
QueryBuilder<${oi.dartName}, ${oi.dartName}, QAfterFilterCondition> ${link.dartName.decapitalize()}IsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.linkLength(r'${link.isarName}', 0, true, 0, true);
|
||||
});
|
||||
}''';
|
||||
} else {
|
||||
code += generateLength(oi.dartName, link.dartName,
|
||||
(lower, includeLower, upper, includeUpper) {
|
||||
return '''
|
||||
QueryBuilder.apply(this, (query) {
|
||||
return query.linkLength(r'${link.isarName}', $lower, $includeLower, $upper, $includeUpper);
|
||||
})''';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return '''
|
||||
$code
|
||||
}''';
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:isar_generator/src/isar_type.dart';
|
||||
import 'package:isar_generator/src/object_info.dart';
|
||||
|
||||
String generateQueryObjects(ObjectInfo oi) {
|
||||
var code =
|
||||
'extension ${oi.dartName}QueryObject on QueryBuilder<${oi.dartName}, '
|
||||
'${oi.dartName}, QFilterCondition> {';
|
||||
for (final property in oi.objectProperties) {
|
||||
if (!property.isarType.containsObject) {
|
||||
continue;
|
||||
}
|
||||
var name = property.dartName.decapitalize();
|
||||
if (property.isarType.isList) {
|
||||
name += 'Element';
|
||||
}
|
||||
code += '''
|
||||
QueryBuilder<${oi.dartName}, ${oi.dartName}, QAfterFilterCondition> $name(FilterQuery<${property.typeClassName}> q) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.object(q, r'${property.isarName}');
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
return '''
|
||||
$code
|
||||
}''';
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
import 'package:isar_generator/src/object_info.dart';
|
||||
|
||||
String generatePropertyQuery(ObjectInfo oi) {
|
||||
var code = '''
|
||||
extension ${oi.dartName}QueryProperty on QueryBuilder<${oi.dartName}, ${oi.dartName}, QQueryProperty> {''';
|
||||
|
||||
// Ids are always non-nullable regardless of their specified nullability
|
||||
code += '''
|
||||
QueryBuilder<${oi.dartName}, int, QQueryOperations>${oi.idProperty.dartName}Property() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'${oi.idProperty.isarName}');
|
||||
});
|
||||
}''';
|
||||
|
||||
for (final property in oi.objectProperties) {
|
||||
code += '''
|
||||
QueryBuilder<${oi.dartName}, ${property.dartType}, QQueryOperations>${property.dartName}Property() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'${property.isarName}');
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
return '$code}';
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:isar_generator/src/isar_type.dart';
|
||||
|
||||
import 'package:isar_generator/src/object_info.dart';
|
||||
|
||||
String generateSortBy(ObjectInfo oi) {
|
||||
var code = '''
|
||||
extension ${oi.dartName}QuerySortBy on QueryBuilder<${oi.dartName}, ${oi.dartName}, QSortBy> {''';
|
||||
|
||||
for (final property in oi.objectProperties) {
|
||||
if (property.isarType.isList || property.isarType.containsObject) {
|
||||
continue;
|
||||
}
|
||||
|
||||
code += '''
|
||||
QueryBuilder<${oi.dartName}, ${oi.dartName}, QAfterSortBy>sortBy${property.dartName.capitalize()}() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'${property.isarName}', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<${oi.dartName}, ${oi.dartName}, QAfterSortBy>sortBy${property.dartName.capitalize()}Desc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'${property.isarName}', Sort.desc);
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
code += '''
|
||||
}
|
||||
|
||||
extension ${oi.dartName}QuerySortThenBy on QueryBuilder<${oi.dartName}, ${oi.dartName}, QSortThenBy> {''';
|
||||
|
||||
for (final property in oi.properties) {
|
||||
if (property.isarType.isList || property.isarType.containsObject) {
|
||||
continue;
|
||||
}
|
||||
|
||||
code += '''
|
||||
QueryBuilder<${oi.dartName}, ${oi.dartName}, QAfterSortBy>thenBy${property.dartName.capitalize()}() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'${property.isarName}', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<${oi.dartName}, ${oi.dartName}, QAfterSortBy>thenBy${property.dartName.capitalize()}Desc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'${property.isarName}', Sort.desc);
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
return '$code}';
|
||||
}
|
||||
|
|
@ -1,568 +0,0 @@
|
|||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:isar_generator/src/object_info.dart';
|
||||
|
||||
class WhereGenerator {
|
||||
WhereGenerator(this.object)
|
||||
: objName = object.dartName,
|
||||
id = object.idProperty;
|
||||
final ObjectInfo object;
|
||||
final String objName;
|
||||
final ObjectProperty id;
|
||||
final existing = <String>{};
|
||||
|
||||
String generate() {
|
||||
var code = 'extension ${objName}QueryWhereSort on QueryBuilder<$objName, '
|
||||
'$objName, QWhere> {';
|
||||
|
||||
code += generateAnyId();
|
||||
for (final index in object.indexes) {
|
||||
if (index.properties.all((element) => element.type == IndexType.value)) {
|
||||
code += generateAny(index);
|
||||
}
|
||||
}
|
||||
|
||||
code += '''
|
||||
}
|
||||
|
||||
extension ${objName}QueryWhere on QueryBuilder<$objName, $objName, QWhereClause> {
|
||||
''';
|
||||
|
||||
code += generateWhereIdEqualTo();
|
||||
code += generateWhereIdNotEqualTo();
|
||||
code += generateWhereIdGreaterThan();
|
||||
code += generateWhereIdLessThan();
|
||||
code += generateWhereIdBetween();
|
||||
|
||||
for (final index in object.indexes) {
|
||||
for (var n = 0; n < index.properties.length; n++) {
|
||||
final indexProperty = index.properties[n];
|
||||
final property = indexProperty.property;
|
||||
|
||||
if ((property.nullable && !indexProperty.isMultiEntry) ||
|
||||
(property.elementNullable && indexProperty.isMultiEntry)) {
|
||||
code += generateWhereIsNull(index, n + 1);
|
||||
code += generateWhereIsNotNull(index, n + 1);
|
||||
}
|
||||
|
||||
code += generateWhereEqualTo(index, n + 1);
|
||||
code += generateWhereNotEqualTo(index, n + 1);
|
||||
|
||||
if (indexProperty.type == IndexType.value) {
|
||||
if (property.isarType != IsarType.bool &&
|
||||
property.isarType != IsarType.boolList) {
|
||||
code += generateWhereGreaterThan(index, n + 1);
|
||||
code += generateWhereLessThan(index, n + 1);
|
||||
code += generateWhereBetween(index, n + 1);
|
||||
}
|
||||
|
||||
if (property.isarType == IsarType.string ||
|
||||
property.isarType == IsarType.stringList) {
|
||||
code += generateWhereStartsWith(index, n + 1);
|
||||
code += generateStringIsEmpty(index, n + 1);
|
||||
code += generateStringIsNotEmpty(index, n + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '$code}';
|
||||
}
|
||||
|
||||
String getMethodName(ObjectIndex index, int propertyCount, [String? method]) {
|
||||
String propertyName(ObjectIndexProperty p) {
|
||||
var name = p.property.dartName.capitalize();
|
||||
if (p.isMultiEntry) {
|
||||
name += 'Element';
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
var name = '';
|
||||
final eqProperties =
|
||||
index.properties.sublist(0, propertyCount - (method != null ? 1 : 0));
|
||||
if (eqProperties.isNotEmpty) {
|
||||
name += eqProperties.map(propertyName).join();
|
||||
name += 'EqualTo';
|
||||
}
|
||||
|
||||
if (method != null) {
|
||||
name += propertyName(index.properties[propertyCount - 1]);
|
||||
name += method;
|
||||
}
|
||||
|
||||
final remainingProperties = propertyCount < index.properties.length
|
||||
? index.properties.sublist(propertyCount)
|
||||
: null;
|
||||
|
||||
if (remainingProperties != null) {
|
||||
name += 'Any';
|
||||
name += remainingProperties.map(propertyName).join();
|
||||
}
|
||||
|
||||
return name.decapitalize();
|
||||
}
|
||||
|
||||
String paramType(ObjectIndexProperty p) {
|
||||
if (p.property.isarType.isList && p.type == IndexType.hash) {
|
||||
return p.property.dartType;
|
||||
} else {
|
||||
return p.property.nScalarDartType;
|
||||
}
|
||||
}
|
||||
|
||||
String paramName(ObjectIndexProperty p) {
|
||||
if (p.property.isarType.isList && p.type != IndexType.hash) {
|
||||
return '${p.property.dartName}Element';
|
||||
} else {
|
||||
return p.property.dartName;
|
||||
}
|
||||
}
|
||||
|
||||
String joinToParams(List<ObjectIndexProperty> properties) {
|
||||
return properties
|
||||
.map((it) => '${paramType(it)} ${paramName(it)}')
|
||||
.join(',');
|
||||
}
|
||||
|
||||
String joinToValues(List<ObjectIndexProperty> properties) {
|
||||
return properties.map((it) {
|
||||
if (it.property.isarType.isList && it.type != IndexType.hash) {
|
||||
return '${it.property.dartName}Element';
|
||||
} else {
|
||||
return paramName(it);
|
||||
}
|
||||
}).join(', ');
|
||||
}
|
||||
|
||||
String generateAnyId() {
|
||||
return '''
|
||||
QueryBuilder<$objName, $objName, QAfterWhere> any${id.dartName.capitalize()}() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(const IdWhereClause.any());
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateAny(ObjectIndex index) {
|
||||
final name = getMethodName(index, 0);
|
||||
if (!existing.add(name)) {
|
||||
return '';
|
||||
}
|
||||
return '''
|
||||
QueryBuilder<$objName, $objName, QAfterWhere> $name() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(
|
||||
const IndexWhereClause.any(indexName: r'${index.name}'),
|
||||
);
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String get mPrefix => 'QueryBuilder<$objName, $objName, QAfterWhereClause>';
|
||||
|
||||
String generateWhereIdEqualTo() {
|
||||
final idName = id.dartName.decapitalize();
|
||||
return '''
|
||||
$mPrefix ${idName}EqualTo(Id $idName) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(IdWhereClause.between(
|
||||
lower: $idName,
|
||||
upper: $idName,
|
||||
));
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereEqualTo(ObjectIndex index, int propertyCount) {
|
||||
final name = getMethodName(index, propertyCount);
|
||||
if (!existing.add(name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final properties = index.properties.takeFirst(propertyCount);
|
||||
final values = joinToValues(properties);
|
||||
final params = joinToParams(properties);
|
||||
return '''
|
||||
$mPrefix $name($params ${properties.containsFloat ? ', {double epsilon = Query.epsilon,}' : ''}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(IndexWhereClause.equalTo(
|
||||
indexName: r'${index.name}',
|
||||
value: [$values],
|
||||
${properties.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
));
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereIdNotEqualTo() {
|
||||
final idName = id.dartName.decapitalize();
|
||||
return '''
|
||||
$mPrefix ${idName}NotEqualTo(Id $idName) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
if (query.whereSort == Sort.asc) {
|
||||
return query.addWhereClause(
|
||||
IdWhereClause.lessThan(upper: $idName, includeUpper: false),
|
||||
).addWhereClause(
|
||||
IdWhereClause.greaterThan(lower: $idName, includeLower: false),
|
||||
);
|
||||
} else {
|
||||
return query.addWhereClause(
|
||||
IdWhereClause.greaterThan(lower: $idName, includeLower: false),
|
||||
).addWhereClause(
|
||||
IdWhereClause.lessThan(upper: $idName, includeUpper: false),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereNotEqualTo(ObjectIndex index, int propertyCount) {
|
||||
final name = getMethodName(index, propertyCount, 'NotEqualTo');
|
||||
if (!existing.add(name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final properties = index.properties.takeFirst(propertyCount);
|
||||
final params = joinToParams(properties);
|
||||
|
||||
final equalProperties = properties.dropLast(1);
|
||||
final notEqualProperty = properties.last;
|
||||
final equalValues = joinToValues(equalProperties);
|
||||
var notEqualValue = joinToValues([notEqualProperty]);
|
||||
if (equalValues.isNotEmpty) {
|
||||
notEqualValue = ',$notEqualValue';
|
||||
}
|
||||
|
||||
return '''
|
||||
$mPrefix $name($params ${properties.containsFloat ? ', {double epsilon = Query.epsilon,}' : ''}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
if (query.whereSort == Sort.asc) {
|
||||
return query.addWhereClause(IndexWhereClause.between(
|
||||
indexName: r'${index.name}',
|
||||
lower: [$equalValues],
|
||||
upper: [$equalValues $notEqualValue],
|
||||
includeUpper: false,
|
||||
${properties.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
)).addWhereClause(IndexWhereClause.between(
|
||||
indexName: r'${index.name}',
|
||||
lower: [$equalValues $notEqualValue],
|
||||
includeLower: false,
|
||||
upper: [$equalValues],
|
||||
${properties.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
));
|
||||
} else {
|
||||
return query.addWhereClause(IndexWhereClause.between(
|
||||
indexName: r'${index.name}',
|
||||
lower: [$equalValues $notEqualValue],
|
||||
includeLower: false,
|
||||
upper: [$equalValues],
|
||||
${properties.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
)).addWhereClause(IndexWhereClause.between(
|
||||
indexName: r'${index.name}',
|
||||
lower: [$equalValues],
|
||||
upper: [$equalValues $notEqualValue],
|
||||
includeUpper: false,
|
||||
${properties.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereIdGreaterThan() {
|
||||
final idName = id.dartName.decapitalize();
|
||||
return '''
|
||||
$mPrefix ${idName}GreaterThan(Id $idName, {bool include = false}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(
|
||||
IdWhereClause.greaterThan(lower: $idName, includeLower: include),
|
||||
);
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereGreaterThan(ObjectIndex index, int propertyCount) {
|
||||
final name = getMethodName(index, propertyCount, 'GreaterThan');
|
||||
if (!existing.add(name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final properties = index.properties.takeFirst(propertyCount);
|
||||
final optional = [
|
||||
'bool include = false',
|
||||
if (properties.containsFloat) 'double epsilon = Query.epsilon',
|
||||
].join(',');
|
||||
return '''
|
||||
$mPrefix $name(${joinToParams(properties)}, {$optional,}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(IndexWhereClause.between(
|
||||
indexName: r'${index.name}',
|
||||
lower: [${joinToValues(properties)}],
|
||||
includeLower: include,
|
||||
upper: [${joinToValues(properties.dropLast(1))}],
|
||||
${properties.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
));
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereIdLessThan() {
|
||||
final idName = id.dartName.decapitalize();
|
||||
return '''
|
||||
$mPrefix ${idName}LessThan(Id $idName, {bool include = false}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(
|
||||
IdWhereClause.lessThan(upper: $idName, includeUpper: include),
|
||||
);
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereLessThan(ObjectIndex index, int propertyCount) {
|
||||
final name = getMethodName(index, propertyCount, 'LessThan');
|
||||
if (!existing.add(name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final properties = index.properties.takeFirst(propertyCount);
|
||||
final optional = [
|
||||
'bool include = false',
|
||||
if (properties.containsFloat) 'double epsilon = Query.epsilon',
|
||||
].join(',');
|
||||
return '''
|
||||
$mPrefix $name(${joinToParams(properties)}, {$optional,}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(IndexWhereClause.between(
|
||||
indexName: r'${index.name}',
|
||||
lower: [${joinToValues(properties.dropLast(1))}],
|
||||
upper: [${joinToValues(properties)}],
|
||||
includeUpper: include,
|
||||
${properties.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
));
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereIdBetween() {
|
||||
final idName = id.dartName.decapitalize();
|
||||
final lowerName = 'lower${id.dartName.capitalize()}';
|
||||
final upperName = 'upper${id.dartName.capitalize()}';
|
||||
return '''
|
||||
$mPrefix ${idName}Between(Id $lowerName, Id $upperName, {bool includeLower = true, bool includeUpper = true,}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(IdWhereClause.between(
|
||||
lower: $lowerName,
|
||||
includeLower: includeLower,
|
||||
upper: $upperName,
|
||||
includeUpper: includeUpper,
|
||||
));
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereBetween(ObjectIndex index, int propertyCount) {
|
||||
final name = getMethodName(index, propertyCount, 'Between');
|
||||
if (!existing.add(name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final properties = index.properties.takeFirst(propertyCount);
|
||||
final equalProperties = properties.dropLast(1);
|
||||
final betweenProperty = properties.last;
|
||||
var params = joinToParams(equalProperties);
|
||||
if (params.isNotEmpty) {
|
||||
params += ',';
|
||||
}
|
||||
|
||||
final betweenType = paramType(betweenProperty);
|
||||
final lowerName = 'lower${paramName(betweenProperty).capitalize()}';
|
||||
final upperName = 'upper${paramName(betweenProperty).capitalize()}';
|
||||
params += '$betweenType $lowerName, $betweenType $upperName';
|
||||
|
||||
var values = joinToValues(equalProperties);
|
||||
if (values.isNotEmpty) {
|
||||
values += ',';
|
||||
}
|
||||
|
||||
final optional = [
|
||||
'bool includeLower = true',
|
||||
'bool includeUpper = true',
|
||||
if (properties.containsFloat) 'double epsilon = Query.epsilon',
|
||||
].join(',');
|
||||
return '''
|
||||
$mPrefix $name($params, {$optional,}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(IndexWhereClause.between(
|
||||
indexName: r'${index.name}',
|
||||
lower: [$values $lowerName],
|
||||
includeLower: includeLower,
|
||||
upper: [$values $upperName],
|
||||
includeUpper: includeUpper,
|
||||
${properties.containsFloat ? 'epsilon: epsilon,' : ''}
|
||||
));
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereIsNull(ObjectIndex index, int propertyCount) {
|
||||
final name = getMethodName(index, propertyCount, 'IsNull');
|
||||
if (!existing.add(name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final properties = index.properties.takeFirst(propertyCount - 1);
|
||||
var values = joinToValues(properties);
|
||||
if (values.isNotEmpty) {
|
||||
values += ',';
|
||||
}
|
||||
final params = joinToParams(properties);
|
||||
return '''
|
||||
$mPrefix $name($params) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(IndexWhereClause.equalTo(
|
||||
indexName: r'${index.name}',
|
||||
value: [$values null],
|
||||
));
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereIsNotNull(ObjectIndex index, int propertyCount) {
|
||||
final name = getMethodName(index, propertyCount, 'IsNotNull');
|
||||
if (!existing.add(name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final properties = index.properties.takeFirst(propertyCount - 1);
|
||||
var values = joinToValues(properties);
|
||||
if (values.isNotEmpty) {
|
||||
values += ',';
|
||||
}
|
||||
final params = joinToParams(properties);
|
||||
return '''
|
||||
$mPrefix $name($params) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(IndexWhereClause.between(
|
||||
indexName: r'${index.name}',
|
||||
lower: [$values null],
|
||||
includeLower: false,
|
||||
upper: [$values],
|
||||
));
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateWhereStartsWith(ObjectIndex index, int propertyCount) {
|
||||
final name = getMethodName(index, propertyCount, 'StartsWith');
|
||||
if (!existing.add(name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final equalProperties = index.properties.dropLast(1);
|
||||
var params = joinToParams(equalProperties);
|
||||
if (params.isNotEmpty) {
|
||||
params += ',';
|
||||
}
|
||||
|
||||
final prefixProperty = index.properties.last;
|
||||
final prefixName = '${paramName(prefixProperty).capitalize()}Prefix';
|
||||
params += 'String $prefixName';
|
||||
var values = joinToValues(equalProperties);
|
||||
if (values.isNotEmpty) {
|
||||
values += ',';
|
||||
}
|
||||
|
||||
return '''
|
||||
$mPrefix $name($params) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(IndexWhereClause.between(
|
||||
indexName: r'${index.name}',
|
||||
lower: [$values $prefixName],
|
||||
upper: [$values '\$$prefixName\\u{FFFFF}'],
|
||||
));
|
||||
});
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateStringIsEmpty(ObjectIndex index, int propertyCount) {
|
||||
final name = getMethodName(index, propertyCount, 'IsEmpty');
|
||||
if (!existing.add(name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final properties = index.properties.dropLast(1);
|
||||
var values = joinToValues(properties);
|
||||
if (values.isNotEmpty) {
|
||||
values += ',';
|
||||
}
|
||||
final params = joinToParams(properties);
|
||||
|
||||
return '''
|
||||
$mPrefix $name($params) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(IndexWhereClause.equalTo(
|
||||
indexName: r'${index.name}',
|
||||
value: [$values ''],
|
||||
));
|
||||
});
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateStringIsNotEmpty(ObjectIndex index, int propertyCount) {
|
||||
final name = getMethodName(index, propertyCount, 'IsNotEmpty');
|
||||
if (!existing.add(name)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
final properties = index.properties.dropLast(1);
|
||||
var values = joinToValues(properties);
|
||||
if (values.isNotEmpty) {
|
||||
values += ',';
|
||||
}
|
||||
final params = joinToParams(properties);
|
||||
|
||||
return '''
|
||||
$mPrefix $name($params) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
if (query.whereSort == Sort.asc) {
|
||||
return query.addWhereClause(IndexWhereClause.lessThan(
|
||||
indexName: r'${index.name}',
|
||||
upper: [''],
|
||||
)).addWhereClause(IndexWhereClause.greaterThan(
|
||||
indexName: r'${index.name}',
|
||||
lower: [''],
|
||||
));
|
||||
} else {
|
||||
return query.addWhereClause(IndexWhereClause.greaterThan(
|
||||
indexName: r'${index.name}',
|
||||
lower: [''],
|
||||
)).addWhereClause(IndexWhereClause.lessThan(
|
||||
indexName: r'${index.name}',
|
||||
upper: [''],
|
||||
));
|
||||
}
|
||||
});
|
||||
}''';
|
||||
}
|
||||
}
|
||||
|
||||
extension on List<ObjectIndexProperty> {
|
||||
bool get containsFloat =>
|
||||
last.isarType == IsarType.float || last.isarType == IsarType.floatList;
|
||||
}
|
||||
|
|
@ -1,476 +0,0 @@
|
|||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:isar_generator/src/object_info.dart';
|
||||
|
||||
String _prepareSerialize(
|
||||
bool nullable,
|
||||
String value,
|
||||
String Function(String) size,
|
||||
) {
|
||||
var code = '';
|
||||
if (nullable) {
|
||||
code += '''
|
||||
{
|
||||
final value = $value;
|
||||
if (value != null) {''';
|
||||
value = 'value';
|
||||
}
|
||||
code += 'bytesCount += ${size(value)};';
|
||||
if (nullable) {
|
||||
code += '}}';
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
String _prepareSerializeList(
|
||||
bool nullable,
|
||||
bool elementNullable,
|
||||
String value,
|
||||
String size, [
|
||||
String? prepare,
|
||||
]) {
|
||||
var code = '';
|
||||
if (nullable) {
|
||||
code += '''
|
||||
{
|
||||
final list = $value;
|
||||
if (list != null) {''';
|
||||
value = 'list';
|
||||
}
|
||||
code += '''
|
||||
bytesCount += 3 + $value.length * 3;
|
||||
{
|
||||
${prepare ?? ''}
|
||||
for (var i = 0; i < $value.length; i++) {
|
||||
final value = $value[i];''';
|
||||
if (elementNullable) {
|
||||
code += 'if (value != null) {';
|
||||
}
|
||||
code += 'bytesCount += $size;';
|
||||
if (elementNullable) {
|
||||
code += '}';
|
||||
}
|
||||
code += '}}';
|
||||
if (nullable) {
|
||||
code += '}}';
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
String generateEstimateSerialize(ObjectInfo object) {
|
||||
var code = '''
|
||||
int ${object.estimateSizeName}(
|
||||
${object.dartName} object,
|
||||
List<int> offsets,
|
||||
Map<Type, List<int>> allOffsets,
|
||||
) {
|
||||
var bytesCount = offsets.last;''';
|
||||
|
||||
for (final property in object.properties) {
|
||||
final value = 'object.${property.dartName}';
|
||||
|
||||
switch (property.isarType) {
|
||||
case IsarType.string:
|
||||
final enumValue = property.isEnum ? '.${property.enumProperty}' : '';
|
||||
code += _prepareSerialize(
|
||||
property.nullable,
|
||||
value,
|
||||
(value) => '3 + $value$enumValue.length * 3',
|
||||
);
|
||||
break;
|
||||
|
||||
case IsarType.stringList:
|
||||
final enumValue = property.isEnum ? '.${property.enumProperty}' : '';
|
||||
code += _prepareSerializeList(
|
||||
property.nullable,
|
||||
property.elementNullable,
|
||||
value,
|
||||
'value$enumValue.length * 3',
|
||||
);
|
||||
break;
|
||||
|
||||
case IsarType.object:
|
||||
code += _prepareSerialize(
|
||||
property.nullable,
|
||||
value,
|
||||
(value) {
|
||||
return '3 + ${property.targetSchema}.estimateSize($value, '
|
||||
'allOffsets[${property.scalarDartType}]!, allOffsets)';
|
||||
},
|
||||
);
|
||||
break;
|
||||
|
||||
case IsarType.objectList:
|
||||
code += _prepareSerializeList(
|
||||
property.nullable,
|
||||
property.elementNullable,
|
||||
value,
|
||||
'${property.targetSchema}.estimateSize(value, offsets, allOffsets)',
|
||||
'final offsets = allOffsets[${property.scalarDartType}]!;',
|
||||
);
|
||||
break;
|
||||
|
||||
case IsarType.byteList:
|
||||
case IsarType.boolList:
|
||||
code += _prepareSerialize(
|
||||
property.nullable,
|
||||
value,
|
||||
(value) => '3 + $value.length',
|
||||
);
|
||||
break;
|
||||
case IsarType.intList:
|
||||
case IsarType.floatList:
|
||||
code += _prepareSerialize(
|
||||
property.nullable,
|
||||
value,
|
||||
(value) => '3 + $value.length * 4',
|
||||
);
|
||||
break;
|
||||
case IsarType.longList:
|
||||
case IsarType.doubleList:
|
||||
case IsarType.dateTimeList:
|
||||
code += _prepareSerialize(
|
||||
property.nullable,
|
||||
value,
|
||||
(value) => '3 + $value.length * 8',
|
||||
);
|
||||
break;
|
||||
|
||||
// ignore: no_default_cases
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return '''
|
||||
$code
|
||||
return bytesCount;
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateSerialize(ObjectInfo object) {
|
||||
var code = '''
|
||||
void ${object.serializeName}(
|
||||
${object.dartName} object,
|
||||
IsarWriter writer,
|
||||
List<int> offsets,
|
||||
Map<Type, List<int>> allOffsets,
|
||||
) {''';
|
||||
|
||||
for (var i = 0; i < object.objectProperties.length; i++) {
|
||||
final property = object.objectProperties[i];
|
||||
var value = 'object.${property.dartName}';
|
||||
if (property.isEnum) {
|
||||
final nOp = property.nullable ? '?' : '';
|
||||
final elNOp = property.elementNullable ? '?' : '';
|
||||
value = property.isarType.isList
|
||||
? '$value$nOp.map((e) => e$elNOp.${property.enumProperty}).toList()'
|
||||
: '$value$nOp.${property.enumProperty}';
|
||||
}
|
||||
|
||||
switch (property.isarType) {
|
||||
case IsarType.bool:
|
||||
code += 'writer.writeBool(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.byte:
|
||||
code += 'writer.writeByte(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.int:
|
||||
code += 'writer.writeInt(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.float:
|
||||
code += 'writer.writeFloat(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.long:
|
||||
code += 'writer.writeLong(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.double:
|
||||
code += 'writer.writeDouble(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.dateTime:
|
||||
code += 'writer.writeDateTime(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.string:
|
||||
code += 'writer.writeString(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.object:
|
||||
code += '''
|
||||
writer.writeObject<${property.typeClassName}>(
|
||||
offsets[$i],
|
||||
allOffsets,
|
||||
${property.targetSchema}.serialize,
|
||||
$value,
|
||||
);''';
|
||||
break;
|
||||
case IsarType.byteList:
|
||||
code += 'writer.writeByteList(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.boolList:
|
||||
code += 'writer.writeBoolList(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.intList:
|
||||
code += 'writer.writeIntList(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.longList:
|
||||
code += 'writer.writeLongList(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.floatList:
|
||||
code += 'writer.writeFloatList(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.doubleList:
|
||||
code += 'writer.writeDoubleList(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.dateTimeList:
|
||||
code += 'writer.writeDateTimeList(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.stringList:
|
||||
code += 'writer.writeStringList(offsets[$i], $value);';
|
||||
break;
|
||||
case IsarType.objectList:
|
||||
code += '''
|
||||
writer.writeObjectList<${property.typeClassName}>(
|
||||
offsets[$i],
|
||||
allOffsets,
|
||||
${property.targetSchema}.serialize,
|
||||
$value,
|
||||
);''';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return '$code}';
|
||||
}
|
||||
|
||||
String generateDeserialize(ObjectInfo object) {
|
||||
var code = '''
|
||||
${object.dartName} ${object.deserializeName}(
|
||||
Id id,
|
||||
IsarReader reader,
|
||||
List<int> offsets,
|
||||
Map<Type, List<int>> allOffsets,
|
||||
) {
|
||||
final object = ${object.dartName}(''';
|
||||
|
||||
final propertiesByMode =
|
||||
object.properties.groupBy((ObjectProperty p) => p.deserialize);
|
||||
final positional = propertiesByMode[PropertyDeser.positionalParam] ?? [];
|
||||
final sortedPositional =
|
||||
positional.sortedBy((ObjectProperty p) => p.constructorPosition!);
|
||||
for (final p in sortedPositional) {
|
||||
final index = object.objectProperties.indexOf(p);
|
||||
final deser = _deserializeProperty(object, p, 'offsets[$index]');
|
||||
code += '$deser,';
|
||||
}
|
||||
|
||||
final named = propertiesByMode[PropertyDeser.namedParam] ?? [];
|
||||
for (final p in named) {
|
||||
final index = object.objectProperties.indexOf(p);
|
||||
final deser = _deserializeProperty(object, p, 'offsets[$index]');
|
||||
code += '${p.dartName}: $deser,';
|
||||
}
|
||||
|
||||
code += ');';
|
||||
|
||||
final assign = propertiesByMode[PropertyDeser.assign] ?? [];
|
||||
for (final p in assign) {
|
||||
final index = object.objectProperties.indexOf(p);
|
||||
final deser = _deserializeProperty(object, p, 'offsets[$index]');
|
||||
code += 'object.${p.dartName} = $deser;';
|
||||
}
|
||||
|
||||
return '''
|
||||
$code
|
||||
return object;
|
||||
}''';
|
||||
}
|
||||
|
||||
String generateDeserializeProp(ObjectInfo object) {
|
||||
var code = '''
|
||||
P ${object.deserializePropName}<P>(
|
||||
IsarReader reader,
|
||||
int propertyId,
|
||||
int offset,
|
||||
Map<Type,
|
||||
List<int>> allOffsets,
|
||||
) {
|
||||
switch (propertyId) {''';
|
||||
|
||||
for (var i = 0; i < object.objectProperties.length; i++) {
|
||||
final property = object.objectProperties[i];
|
||||
final deser = _deserializeProperty(object, property, 'offset');
|
||||
code += 'case $i: return ($deser) as P;';
|
||||
}
|
||||
|
||||
return '''
|
||||
$code
|
||||
default:
|
||||
throw IsarError('Unknown property with id \$propertyId');
|
||||
}
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String _deserializeProperty(
|
||||
ObjectInfo object,
|
||||
ObjectProperty property,
|
||||
String propertyOffset,
|
||||
) {
|
||||
if (property.isId) {
|
||||
return 'id';
|
||||
}
|
||||
|
||||
final deser = _deserialize(property, propertyOffset);
|
||||
|
||||
var defaultValue = '';
|
||||
if (!property.nullable) {
|
||||
if (property.userDefaultValue != null) {
|
||||
defaultValue = '?? ${property.userDefaultValue}';
|
||||
} else if (property.isarType == IsarType.object) {
|
||||
defaultValue = '?? ${property.typeClassName}()';
|
||||
} else if (property.isarType.isList) {
|
||||
defaultValue = '?? []';
|
||||
} else if (property.isEnum) {
|
||||
defaultValue = '?? ${property.defaultEnumElement}';
|
||||
}
|
||||
}
|
||||
|
||||
if (property.isEnum) {
|
||||
if (property.isarType.isList) {
|
||||
final elDefault =
|
||||
!property.elementNullable ? '?? ${property.defaultEnumElement}' : '';
|
||||
return '$deser?.map((e) => ${property.valueEnumMapName(object)}[e] '
|
||||
'$elDefault).toList() $defaultValue';
|
||||
} else {
|
||||
return '${property.valueEnumMapName(object)}[$deser] $defaultValue';
|
||||
}
|
||||
} else {
|
||||
return '$deser $defaultValue';
|
||||
}
|
||||
}
|
||||
|
||||
String _deserialize(ObjectProperty property, String propertyOffset) {
|
||||
final orNull =
|
||||
property.nullable || property.userDefaultValue != null || property.isEnum
|
||||
? 'OrNull'
|
||||
: '';
|
||||
final orElNull = property.elementNullable ? 'OrNull' : '';
|
||||
|
||||
switch (property.isarType) {
|
||||
case IsarType.bool:
|
||||
return 'reader.readBool$orNull($propertyOffset)';
|
||||
case IsarType.byte:
|
||||
return 'reader.readByte$orNull($propertyOffset)';
|
||||
case IsarType.int:
|
||||
return 'reader.readInt$orNull($propertyOffset)';
|
||||
case IsarType.float:
|
||||
return 'reader.readFloat$orNull($propertyOffset)';
|
||||
case IsarType.long:
|
||||
return 'reader.readLong$orNull($propertyOffset)';
|
||||
case IsarType.double:
|
||||
return 'reader.readDouble$orNull($propertyOffset)';
|
||||
case IsarType.dateTime:
|
||||
return 'reader.readDateTime$orNull($propertyOffset)';
|
||||
case IsarType.string:
|
||||
return 'reader.readString$orNull($propertyOffset)';
|
||||
case IsarType.object:
|
||||
return '''
|
||||
reader.readObjectOrNull<${property.typeClassName}>(
|
||||
$propertyOffset,
|
||||
${property.targetSchema}.deserialize,
|
||||
allOffsets,
|
||||
)''';
|
||||
case IsarType.boolList:
|
||||
return 'reader.readBool${orElNull}List($propertyOffset)';
|
||||
case IsarType.byteList:
|
||||
return 'reader.readByteList($propertyOffset)';
|
||||
case IsarType.intList:
|
||||
return 'reader.readInt${orElNull}List($propertyOffset)';
|
||||
case IsarType.floatList:
|
||||
return 'reader.readFloat${orElNull}List($propertyOffset)';
|
||||
case IsarType.longList:
|
||||
return 'reader.readLong${orElNull}List($propertyOffset)';
|
||||
case IsarType.doubleList:
|
||||
return 'reader.readDouble${orElNull}List($propertyOffset)';
|
||||
case IsarType.dateTimeList:
|
||||
return 'reader.readDateTime${orElNull}List($propertyOffset)';
|
||||
case IsarType.stringList:
|
||||
return 'reader.readString${orElNull}List($propertyOffset)';
|
||||
case IsarType.objectList:
|
||||
return '''
|
||||
reader.readObject${orElNull}List<${property.typeClassName}>(
|
||||
$propertyOffset,
|
||||
${property.targetSchema}.deserialize,
|
||||
allOffsets,
|
||||
${!property.elementNullable ? '${property.typeClassName}(),' : ''}
|
||||
)''';
|
||||
}
|
||||
}
|
||||
|
||||
String generateGetId(ObjectInfo object) {
|
||||
final defaultVal = object.idProperty.nullable ? '?? Isar.autoIncrement' : '';
|
||||
return '''
|
||||
Id ${object.getIdName}(${object.dartName} object) {
|
||||
return object.${object.idProperty.dartName} $defaultVal;
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateGetLinks(ObjectInfo object) {
|
||||
return '''
|
||||
List<IsarLinkBase<dynamic>> ${object.getLinksName}(${object.dartName} object) {
|
||||
return [${object.links.map((e) => 'object.${e.dartName}').join(',')}];
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
String generateAttach(ObjectInfo object) {
|
||||
var code = '''
|
||||
void ${object.attachName}(IsarCollection<dynamic> col, Id id, ${object.dartName} object) {''';
|
||||
|
||||
if (object.idProperty.assignable) {
|
||||
code += 'object.${object.idProperty.dartName} = id;';
|
||||
}
|
||||
|
||||
for (final link in object.links) {
|
||||
// ignore: leading_newlines_in_multiline_strings
|
||||
code += '''object.${link.dartName}.attach(
|
||||
col,
|
||||
col.isar.collection<${link.targetCollectionDartName}>(),
|
||||
r'${link.isarName}',
|
||||
id
|
||||
);''';
|
||||
}
|
||||
return '$code}';
|
||||
}
|
||||
|
||||
String generateEnumMaps(ObjectInfo object) {
|
||||
var code = '';
|
||||
for (final property in object.properties) {
|
||||
final enumName = property.typeClassName;
|
||||
if (property.isEnum) {
|
||||
code += 'const ${property.enumValueMapName(object)} = {';
|
||||
for (final enumElementName in property.enumMap!.keys) {
|
||||
final value = property.enumMap![enumElementName];
|
||||
if (value is String) {
|
||||
code += "r'$enumElementName': r'$value',";
|
||||
} else {
|
||||
code += "'$enumElementName': $value,";
|
||||
}
|
||||
}
|
||||
code += '};';
|
||||
|
||||
code += 'const ${property.valueEnumMapName(object)} = {';
|
||||
for (final enumElementName in property.enumMap!.keys) {
|
||||
final value = property.enumMap![enumElementName];
|
||||
if (value is String) {
|
||||
code += "r'$value': $enumName.$enumElementName,";
|
||||
} else {
|
||||
code += '$value: $enumName.$enumElementName,';
|
||||
}
|
||||
}
|
||||
code += '};';
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:build/build.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:isar_generator/src/code_gen/by_index_generator.dart';
|
||||
import 'package:isar_generator/src/code_gen/collection_schema_generator.dart';
|
||||
import 'package:isar_generator/src/code_gen/query_distinct_by_generator.dart';
|
||||
import 'package:isar_generator/src/code_gen/query_filter_generator.dart';
|
||||
import 'package:isar_generator/src/code_gen/query_link_generator.dart';
|
||||
import 'package:isar_generator/src/code_gen/query_object_generator.dart';
|
||||
import 'package:isar_generator/src/code_gen/query_property_generator.dart';
|
||||
import 'package:isar_generator/src/code_gen/query_sort_by_generator.dart';
|
||||
import 'package:isar_generator/src/code_gen/query_where_generator.dart';
|
||||
import 'package:isar_generator/src/code_gen/type_adapter_generator.dart';
|
||||
import 'package:isar_generator/src/isar_analyzer.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
const ignoreLints = [
|
||||
'duplicate_ignore',
|
||||
'non_constant_identifier_names',
|
||||
'constant_identifier_names',
|
||||
'invalid_use_of_protected_member',
|
||||
'unnecessary_cast',
|
||||
'prefer_const_constructors',
|
||||
'lines_longer_than_80_chars',
|
||||
'require_trailing_commas',
|
||||
'inference_failure_on_function_invocation',
|
||||
'unnecessary_parenthesis',
|
||||
'unnecessary_raw_strings',
|
||||
'unnecessary_null_checks',
|
||||
'join_return_with_assignment',
|
||||
'prefer_final_locals',
|
||||
'avoid_js_rounded_ints',
|
||||
'avoid_positional_boolean_parameters',
|
||||
'always_specify_types',
|
||||
];
|
||||
|
||||
class IsarCollectionGenerator extends GeneratorForAnnotation<Collection> {
|
||||
@override
|
||||
Future<String> generateForAnnotatedElement(
|
||||
Element element,
|
||||
ConstantReader annotation,
|
||||
BuildStep buildStep,
|
||||
) async {
|
||||
final object = IsarAnalyzer().analyzeCollection(element);
|
||||
return '''
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: ${ignoreLints.join(', ')}
|
||||
|
||||
extension Get${object.dartName}Collection on Isar {
|
||||
IsarCollection<${object.dartName}> get ${object.accessor} => this.collection();
|
||||
}
|
||||
|
||||
${generateSchema(object)}
|
||||
|
||||
${generateEstimateSerialize(object)}
|
||||
${generateSerialize(object)}
|
||||
${generateDeserialize(object)}
|
||||
${generateDeserializeProp(object)}
|
||||
|
||||
${generateEnumMaps(object)}
|
||||
|
||||
${generateGetId(object)}
|
||||
${generateGetLinks(object)}
|
||||
${generateAttach(object)}
|
||||
|
||||
${generateByIndexExtension(object)}
|
||||
${WhereGenerator(object).generate()}
|
||||
${FilterGenerator(object).generate()}
|
||||
${generateQueryObjects(object)}
|
||||
${generateQueryLinks(object)}
|
||||
${generateSortBy(object)}
|
||||
${generateDistinctBy(object)}
|
||||
${generatePropertyQuery(object)}
|
||||
''';
|
||||
}
|
||||
}
|
||||
|
||||
class IsarEmbeddedGenerator extends GeneratorForAnnotation<Embedded> {
|
||||
@override
|
||||
Future<String> generateForAnnotatedElement(
|
||||
Element element,
|
||||
ConstantReader annotation,
|
||||
BuildStep buildStep,
|
||||
) async {
|
||||
final object = IsarAnalyzer().analyzeEmbedded(element);
|
||||
return '''
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: ${ignoreLints.join(', ')}
|
||||
|
||||
${generateSchema(object)}
|
||||
|
||||
${generateEstimateSerialize(object)}
|
||||
${generateSerialize(object)}
|
||||
${generateDeserialize(object)}
|
||||
${generateDeserializeProp(object)}
|
||||
|
||||
${generateEnumMaps(object)}
|
||||
|
||||
${FilterGenerator(object).generate()}
|
||||
${generateQueryObjects(object)}
|
||||
''';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
import 'package:analyzer/dart/constant/value.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
const TypeChecker _collectionChecker = TypeChecker.fromRuntime(Collection);
|
||||
const TypeChecker _enumeratedChecker = TypeChecker.fromRuntime(Enumerated);
|
||||
const TypeChecker _embeddedChecker = TypeChecker.fromRuntime(Embedded);
|
||||
const TypeChecker _ignoreChecker = TypeChecker.fromRuntime(Ignore);
|
||||
const TypeChecker _nameChecker = TypeChecker.fromRuntime(Name);
|
||||
const TypeChecker _indexChecker = TypeChecker.fromRuntime(Index);
|
||||
const TypeChecker _backlinkChecker = TypeChecker.fromRuntime(Backlink);
|
||||
|
||||
extension ClassElementX on ClassElement {
|
||||
bool get hasZeroArgsConstructor {
|
||||
return constructors.any(
|
||||
(ConstructorElement c) =>
|
||||
c.isPublic &&
|
||||
!c.parameters.any((ParameterElement p) => !p.isOptional),
|
||||
);
|
||||
}
|
||||
|
||||
List<PropertyInducingElement> get allAccessors {
|
||||
final ignoreFields =
|
||||
collectionAnnotation?.ignore ?? embeddedAnnotation!.ignore;
|
||||
return [
|
||||
...accessors.mapNotNull((e) => e.variable),
|
||||
if (collectionAnnotation?.inheritance ?? embeddedAnnotation!.inheritance)
|
||||
for (InterfaceType supertype in allSupertypes) ...[
|
||||
if (!supertype.isDartCoreObject)
|
||||
...supertype.accessors.mapNotNull((e) => e.variable)
|
||||
]
|
||||
]
|
||||
.where(
|
||||
(PropertyInducingElement e) =>
|
||||
e.isPublic &&
|
||||
!e.isStatic &&
|
||||
!_ignoreChecker.hasAnnotationOf(e.nonSynthetic) &&
|
||||
!ignoreFields.contains(e.name),
|
||||
)
|
||||
.distinctBy((e) => e.name)
|
||||
.toList();
|
||||
}
|
||||
|
||||
List<String> get enumConsts {
|
||||
return fields.where((e) => e.isEnumConstant).map((e) => e.name).toList();
|
||||
}
|
||||
}
|
||||
|
||||
extension PropertyElementX on PropertyInducingElement {
|
||||
bool get isLink => type.element2!.name == 'IsarLink';
|
||||
|
||||
bool get isLinks => type.element2!.name == 'IsarLinks';
|
||||
|
||||
Enumerated? get enumeratedAnnotation {
|
||||
final ann = _enumeratedChecker.firstAnnotationOfExact(nonSynthetic);
|
||||
if (ann == null) {
|
||||
return null;
|
||||
}
|
||||
final typeIndex = ann.getField('type')!.getField('index')!.toIntValue()!;
|
||||
return Enumerated(
|
||||
EnumType.values[typeIndex],
|
||||
ann.getField('property')?.toStringValue(),
|
||||
);
|
||||
}
|
||||
|
||||
Backlink? get backlinkAnnotation {
|
||||
final ann = _backlinkChecker.firstAnnotationOfExact(nonSynthetic);
|
||||
if (ann == null) {
|
||||
return null;
|
||||
}
|
||||
return Backlink(to: ann.getField('to')!.toStringValue()!);
|
||||
}
|
||||
|
||||
List<Index> get indexAnnotations {
|
||||
return _indexChecker.annotationsOfExact(nonSynthetic).map((DartObject ann) {
|
||||
final rawComposite = ann.getField('composite')!.toListValue();
|
||||
final composite = <CompositeIndex>[];
|
||||
if (rawComposite != null) {
|
||||
for (final c in rawComposite) {
|
||||
final indexTypeField = c.getField('type')!;
|
||||
IndexType? indexType;
|
||||
if (!indexTypeField.isNull) {
|
||||
final indexTypeIndex =
|
||||
indexTypeField.getField('index')!.toIntValue()!;
|
||||
indexType = IndexType.values[indexTypeIndex];
|
||||
}
|
||||
composite.add(
|
||||
CompositeIndex(
|
||||
c.getField('property')!.toStringValue()!,
|
||||
type: indexType,
|
||||
caseSensitive: c.getField('caseSensitive')!.toBoolValue(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
final indexTypeField = ann.getField('type')!;
|
||||
IndexType? indexType;
|
||||
if (!indexTypeField.isNull) {
|
||||
final indexTypeIndex = indexTypeField.getField('index')!.toIntValue()!;
|
||||
indexType = IndexType.values[indexTypeIndex];
|
||||
}
|
||||
return Index(
|
||||
name: ann.getField('name')!.toStringValue(),
|
||||
composite: composite,
|
||||
unique: ann.getField('unique')!.toBoolValue()!,
|
||||
replace: ann.getField('replace')!.toBoolValue()!,
|
||||
type: indexType,
|
||||
caseSensitive: ann.getField('caseSensitive')!.toBoolValue(),
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
|
||||
extension ElementX on Element {
|
||||
String get isarName {
|
||||
final ann = _nameChecker.firstAnnotationOfExact(nonSynthetic);
|
||||
late String name;
|
||||
if (ann == null) {
|
||||
name = displayName;
|
||||
} else {
|
||||
name = ann.getField('name')!.toStringValue()!;
|
||||
}
|
||||
checkIsarName(name, this);
|
||||
return name;
|
||||
}
|
||||
|
||||
Collection? get collectionAnnotation {
|
||||
final ann = _collectionChecker.firstAnnotationOfExact(nonSynthetic);
|
||||
if (ann == null) {
|
||||
return null;
|
||||
}
|
||||
return Collection(
|
||||
inheritance: ann.getField('inheritance')!.toBoolValue()!,
|
||||
accessor: ann.getField('accessor')!.toStringValue(),
|
||||
ignore: ann
|
||||
.getField('ignore')!
|
||||
.toSetValue()!
|
||||
.map((e) => e.toStringValue()!)
|
||||
.toSet(),
|
||||
);
|
||||
}
|
||||
|
||||
String get collectionAccessor {
|
||||
var accessor = collectionAnnotation?.accessor;
|
||||
if (accessor != null) {
|
||||
return accessor;
|
||||
}
|
||||
|
||||
accessor = displayName.decapitalize();
|
||||
if (!accessor.endsWith('s')) {
|
||||
accessor += 's';
|
||||
}
|
||||
|
||||
return accessor;
|
||||
}
|
||||
|
||||
Embedded? get embeddedAnnotation {
|
||||
final ann = _embeddedChecker.firstAnnotationOfExact(nonSynthetic);
|
||||
if (ann == null) {
|
||||
return null;
|
||||
}
|
||||
return Embedded(
|
||||
inheritance: ann.getField('inheritance')!.toBoolValue()!,
|
||||
ignore: ann
|
||||
.getField('ignore')!
|
||||
.toSetValue()!
|
||||
.map((e) => e.toStringValue()!)
|
||||
.toSet(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void checkIsarName(String name, Element element) {
|
||||
if (name.isBlank || name.startsWith('_')) {
|
||||
err('Names must not be blank or start with "_".', element);
|
||||
}
|
||||
}
|
||||
|
||||
Never err(String msg, [Element? element]) {
|
||||
throw InvalidGenerationSourceError(msg, element: element);
|
||||
}
|
||||
|
|
@ -1,502 +0,0 @@
|
|||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/nullability_suffix.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
import 'package:isar_generator/src/helper.dart';
|
||||
import 'package:isar_generator/src/isar_type.dart';
|
||||
import 'package:isar_generator/src/object_info.dart';
|
||||
|
||||
class IsarAnalyzer {
|
||||
ObjectInfo analyzeCollection(Element element) {
|
||||
final constructor = _checkValidClass(element);
|
||||
final modelClass = element as ClassElement;
|
||||
|
||||
final properties = <ObjectProperty>[];
|
||||
final links = <ObjectLink>[];
|
||||
for (final propertyElement in modelClass.allAccessors) {
|
||||
if (propertyElement.isLink || propertyElement.isLinks) {
|
||||
final link = analyzeObjectLink(propertyElement);
|
||||
links.add(link);
|
||||
} else {
|
||||
final property = analyzeObjectProperty(propertyElement, constructor);
|
||||
properties.add(property);
|
||||
}
|
||||
}
|
||||
_checkValidPropertiesConstructor(properties, constructor);
|
||||
if (links.map((e) => e.isarName).distinct().length != links.length) {
|
||||
err('Two or more links have the same name.', modelClass);
|
||||
}
|
||||
|
||||
final indexes = <ObjectIndex>[];
|
||||
for (final propertyElement in modelClass.allAccessors) {
|
||||
indexes.addAll(analyzeObjectIndex(properties, propertyElement));
|
||||
}
|
||||
if (indexes.map((e) => e.name).distinct().length != indexes.length) {
|
||||
err('Two or more indexes have the same name.', modelClass);
|
||||
}
|
||||
|
||||
final idProperties = properties.where((it) => it.isId);
|
||||
if (idProperties.isEmpty) {
|
||||
err(
|
||||
'No id property defined. Use the "Id" type for your id property.',
|
||||
modelClass,
|
||||
);
|
||||
} else if (idProperties.length > 1) {
|
||||
err('Two or more properties with type "Id" defined.', modelClass);
|
||||
}
|
||||
|
||||
return ObjectInfo(
|
||||
dartName: modelClass.displayName,
|
||||
isarName: modelClass.isarName,
|
||||
accessor: modelClass.collectionAccessor,
|
||||
properties: properties,
|
||||
embeddedDartNames: _getEmbeddedDartNames(element),
|
||||
indexes: indexes,
|
||||
links: links,
|
||||
);
|
||||
}
|
||||
|
||||
ObjectInfo analyzeEmbedded(Element element) {
|
||||
final constructor = _checkValidClass(element);
|
||||
final modelClass = element as ClassElement;
|
||||
|
||||
if (constructor.parameters.any((e) => e.isRequired)) {
|
||||
err(
|
||||
'Constructors of embedded objects must not have required parameters.',
|
||||
constructor,
|
||||
);
|
||||
}
|
||||
|
||||
final properties = <ObjectProperty>[];
|
||||
for (final propertyElement in modelClass.allAccessors) {
|
||||
if (propertyElement.isLink || propertyElement.isLinks) {
|
||||
err('Embedded objects must not contain links', propertyElement);
|
||||
} else {
|
||||
final property = analyzeObjectProperty(propertyElement, constructor);
|
||||
properties.add(property);
|
||||
}
|
||||
}
|
||||
_checkValidPropertiesConstructor(properties, constructor);
|
||||
|
||||
final hasIndex = modelClass.allAccessors.any(
|
||||
(it) => it.indexAnnotations.isNotEmpty,
|
||||
);
|
||||
if (hasIndex) {
|
||||
err('Embedded objects must not have indexes.', modelClass);
|
||||
}
|
||||
|
||||
final hasIdProperty = properties.any((it) => it.isId);
|
||||
if (hasIdProperty) {
|
||||
err('Embedded objects must not define an id.', modelClass);
|
||||
}
|
||||
|
||||
return ObjectInfo(
|
||||
dartName: modelClass.displayName,
|
||||
isarName: modelClass.isarName,
|
||||
properties: properties,
|
||||
);
|
||||
}
|
||||
|
||||
ConstructorElement _checkValidClass(Element modelClass) {
|
||||
if (modelClass is! ClassElement ||
|
||||
modelClass is EnumElement ||
|
||||
modelClass is MixinElement) {
|
||||
err(
|
||||
'Only classes may be annotated with @Collection or @Embedded.',
|
||||
modelClass,
|
||||
);
|
||||
}
|
||||
|
||||
if (modelClass.isAbstract) {
|
||||
err('Class must not be abstract.', modelClass);
|
||||
}
|
||||
|
||||
if (!modelClass.isPublic) {
|
||||
err('Class must be public.', modelClass);
|
||||
}
|
||||
|
||||
final constructor = modelClass.constructors
|
||||
.firstOrNullWhere((ConstructorElement c) => c.periodOffset == null);
|
||||
if (constructor == null) {
|
||||
err('Class needs an unnamed constructor.', modelClass);
|
||||
}
|
||||
|
||||
final hasCollectionSupertype = modelClass.allSupertypes.any((type) {
|
||||
return type.element.collectionAnnotation != null ||
|
||||
type.element.embeddedAnnotation != null;
|
||||
});
|
||||
if (hasCollectionSupertype) {
|
||||
err(
|
||||
'Class must not have a supertype annotated with @Collection or '
|
||||
'@Embedded.',
|
||||
modelClass,
|
||||
);
|
||||
}
|
||||
|
||||
return constructor;
|
||||
}
|
||||
|
||||
void _checkValidPropertiesConstructor(
|
||||
List<ObjectProperty> properties,
|
||||
ConstructorElement constructor,
|
||||
) {
|
||||
if (properties.map((e) => e.isarName).distinct().length !=
|
||||
properties.length) {
|
||||
err(
|
||||
'Two or more properties have the same name.',
|
||||
constructor.enclosingElement,
|
||||
);
|
||||
}
|
||||
|
||||
final unknownConstructorParameter = constructor.parameters.firstOrNullWhere(
|
||||
(p) => p.isRequired && properties.none((e) => e.dartName == p.name),
|
||||
);
|
||||
if (unknownConstructorParameter != null) {
|
||||
err(
|
||||
'Constructor parameter does not match a property.',
|
||||
unknownConstructorParameter,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> _getEmbeddedDartNames(ClassElement element) {
|
||||
void _fillNames(Map<String, String> names, ClassElement element) {
|
||||
for (final property in element.allAccessors) {
|
||||
final type = property.type.scalarType.element;
|
||||
if (type is ClassElement && type.embeddedAnnotation != null) {
|
||||
final isarName = type.isarName;
|
||||
if (!names.containsKey(isarName)) {
|
||||
names[type.isarName] = type.displayName;
|
||||
_fillNames(names, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final names = <String, String>{};
|
||||
_fillNames(names, element);
|
||||
return names;
|
||||
}
|
||||
|
||||
ObjectProperty analyzeObjectProperty(
|
||||
PropertyInducingElement property,
|
||||
ConstructorElement constructor,
|
||||
) {
|
||||
final dartType = property.type;
|
||||
final scalarDartType = dartType.scalarType;
|
||||
Map<String, dynamic>? enumMap;
|
||||
String? enumPropertyName;
|
||||
String? defaultEnumElement;
|
||||
|
||||
late final IsarType isarType;
|
||||
if (scalarDartType.element is EnumElement) {
|
||||
final enumeratedAnn = property.enumeratedAnnotation;
|
||||
if (enumeratedAnn == null) {
|
||||
err('Enum property must be annotated with @enumerated.', property);
|
||||
}
|
||||
|
||||
final enumClass = scalarDartType.element! as EnumElement;
|
||||
final enumElements =
|
||||
enumClass.fields.where((f) => f.isEnumConstant).toList();
|
||||
defaultEnumElement = '${enumClass.name}.${enumElements.first.name}';
|
||||
|
||||
if (enumeratedAnn.type == EnumType.ordinal) {
|
||||
isarType = dartType.isDartCoreList ? IsarType.byteList : IsarType.byte;
|
||||
enumMap = {
|
||||
for (var i = 0; i < enumElements.length; i++) enumElements[i].name: i,
|
||||
};
|
||||
enumPropertyName = 'index';
|
||||
} else if (enumeratedAnn.type == EnumType.ordinal32) {
|
||||
isarType = dartType.isDartCoreList ? IsarType.intList : IsarType.int;
|
||||
|
||||
enumMap = {
|
||||
for (var i = 0; i < enumElements.length; i++) enumElements[i].name: i,
|
||||
};
|
||||
enumPropertyName = 'index';
|
||||
} else if (enumeratedAnn.type == EnumType.name) {
|
||||
isarType =
|
||||
dartType.isDartCoreList ? IsarType.stringList : IsarType.string;
|
||||
enumMap = {
|
||||
for (final value in enumElements) value.name: value.name,
|
||||
};
|
||||
enumPropertyName = 'name';
|
||||
} else {
|
||||
enumPropertyName = enumeratedAnn.property;
|
||||
if (enumPropertyName == null) {
|
||||
err(
|
||||
'Enums with type EnumType.value must specify which property '
|
||||
'should be used.',
|
||||
property,
|
||||
);
|
||||
}
|
||||
final enumProperty = enumClass.getField(enumPropertyName);
|
||||
if (enumProperty == null || enumProperty.isEnumConstant) {
|
||||
err('Enum property "$enumProperty" does not exist.', property);
|
||||
} else if (enumProperty.nonSynthetic is PropertyAccessorElement) {
|
||||
err('Only fields are supported for enum properties', enumProperty);
|
||||
}
|
||||
|
||||
final enumIsarType = enumProperty.type.isarType;
|
||||
if (enumIsarType != IsarType.byte &&
|
||||
enumIsarType != IsarType.int &&
|
||||
enumIsarType != IsarType.long &&
|
||||
enumIsarType != IsarType.string) {
|
||||
err('Unsupported enum property type.', enumProperty);
|
||||
}
|
||||
|
||||
isarType =
|
||||
dartType.isDartCoreList ? enumIsarType!.listType : enumIsarType!;
|
||||
enumMap = {};
|
||||
for (final element in enumElements) {
|
||||
final property =
|
||||
element.computeConstantValue()!.getField(enumPropertyName)!;
|
||||
final propertyValue = property.toBoolValue() ??
|
||||
property.toIntValue() ??
|
||||
property.toDoubleValue() ??
|
||||
property.toStringValue();
|
||||
if (propertyValue == null) {
|
||||
err(
|
||||
'Null values are not supported for enum properties.',
|
||||
enumProperty,
|
||||
);
|
||||
}
|
||||
|
||||
if (enumMap.values.contains(propertyValue)) {
|
||||
err(
|
||||
'Enum property has duplicate values.',
|
||||
enumProperty,
|
||||
);
|
||||
}
|
||||
enumMap[element.name] = propertyValue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dartType.isarType != null) {
|
||||
isarType = dartType.isarType!;
|
||||
} else {
|
||||
err(
|
||||
'Unsupported type. Please annotate the property with @ignore.',
|
||||
property,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final nullable = dartType.nullabilitySuffix != NullabilitySuffix.none;
|
||||
final elementNullable = isarType.isList &&
|
||||
dartType.scalarType.nullabilitySuffix != NullabilitySuffix.none;
|
||||
|
||||
if ((isarType == IsarType.byte && nullable) ||
|
||||
(isarType == IsarType.byteList && elementNullable)) {
|
||||
err('Bytes must not be nullable.', property);
|
||||
}
|
||||
|
||||
final constructorParameter =
|
||||
constructor.parameters.firstOrNullWhere((p) => p.name == property.name);
|
||||
int? constructorPosition;
|
||||
late PropertyDeser deserialize;
|
||||
if (constructorParameter != null) {
|
||||
if (constructorParameter.type != property.type) {
|
||||
err(
|
||||
'Constructor parameter type does not match property type',
|
||||
constructorParameter,
|
||||
);
|
||||
}
|
||||
deserialize = constructorParameter.isNamed
|
||||
? PropertyDeser.namedParam
|
||||
: PropertyDeser.positionalParam;
|
||||
constructorPosition =
|
||||
constructor.parameters.indexOf(constructorParameter);
|
||||
} else {
|
||||
deserialize =
|
||||
property.setter == null ? PropertyDeser.none : PropertyDeser.assign;
|
||||
}
|
||||
|
||||
return ObjectProperty(
|
||||
dartName: property.displayName,
|
||||
isarName: property.isarName,
|
||||
typeClassName: dartType.scalarType.element!.name!,
|
||||
targetIsarName: isarType.containsObject
|
||||
? dartType.scalarType.element!.isarName
|
||||
: null,
|
||||
isarType: isarType,
|
||||
isId: dartType.isIsarId,
|
||||
enumMap: enumMap,
|
||||
enumProperty: enumPropertyName,
|
||||
defaultEnumElement: defaultEnumElement,
|
||||
nullable: nullable,
|
||||
elementNullable: elementNullable,
|
||||
userDefaultValue: constructorParameter?.defaultValueCode,
|
||||
deserialize: deserialize,
|
||||
assignable: property.setter != null,
|
||||
constructorPosition: constructorPosition,
|
||||
);
|
||||
}
|
||||
|
||||
ObjectLink analyzeObjectLink(PropertyInducingElement property) {
|
||||
if (property.type.nullabilitySuffix != NullabilitySuffix.none) {
|
||||
err('Link properties must not be nullable.', property);
|
||||
} else if (property.isLate) {
|
||||
err('Link properties must not be late.', property);
|
||||
}
|
||||
|
||||
final type = property.type as ParameterizedType;
|
||||
final linkType = type.typeArguments[0];
|
||||
if (linkType.nullabilitySuffix != NullabilitySuffix.none) {
|
||||
err('Links type must not be nullable.', property);
|
||||
}
|
||||
|
||||
final targetCol = linkType.element! as ClassElement;
|
||||
if (targetCol.collectionAnnotation == null) {
|
||||
err('Link target is not annotated with @collection');
|
||||
}
|
||||
|
||||
final backlinkAnn = property.backlinkAnnotation;
|
||||
String? targetLinkIsarName;
|
||||
if (backlinkAnn != null) {
|
||||
final targetProperty = targetCol.allAccessors
|
||||
.firstOrNullWhere((e) => e.displayName == backlinkAnn.to);
|
||||
if (targetProperty == null) {
|
||||
err('Target of Backlink does not exist', property);
|
||||
} else if (targetProperty.backlinkAnnotation != null) {
|
||||
err('Target of Backlink is also a backlink', property);
|
||||
}
|
||||
|
||||
if (!targetProperty.isLink && !targetProperty.isLinks) {
|
||||
err('Target of backlink is not a link', property);
|
||||
}
|
||||
|
||||
final targetLink = analyzeObjectLink(targetProperty);
|
||||
targetLinkIsarName = targetLink.isarName;
|
||||
}
|
||||
|
||||
return ObjectLink(
|
||||
dartName: property.displayName,
|
||||
isarName: property.isarName,
|
||||
targetLinkIsarName: targetLinkIsarName,
|
||||
targetCollectionDartName: linkType.element!.name!,
|
||||
targetCollectionIsarName: targetCol.isarName,
|
||||
isSingle: property.isLink,
|
||||
);
|
||||
}
|
||||
|
||||
Iterable<ObjectIndex> analyzeObjectIndex(
|
||||
List<ObjectProperty> properties,
|
||||
PropertyInducingElement element,
|
||||
) sync* {
|
||||
final property =
|
||||
properties.firstOrNullWhere((it) => it.dartName == element.name);
|
||||
if (property == null || property.isId) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final index in element.indexAnnotations) {
|
||||
final indexProperties = <ObjectIndexProperty>[];
|
||||
final isString = property.isarType == IsarType.string ||
|
||||
property.isarType == IsarType.stringList;
|
||||
final defaultType = property.isarType.isList || isString
|
||||
? IndexType.hash
|
||||
: IndexType.value;
|
||||
|
||||
indexProperties.add(
|
||||
ObjectIndexProperty(
|
||||
property: property,
|
||||
type: index.type ?? defaultType,
|
||||
caseSensitive: index.caseSensitive ?? isString,
|
||||
),
|
||||
);
|
||||
for (final c in index.composite) {
|
||||
final compositeProperty =
|
||||
properties.firstOrNullWhere((it) => it.dartName == c.property);
|
||||
if (compositeProperty == null) {
|
||||
err('Property does not exist: "${c.property}".', element);
|
||||
} else if (compositeProperty.isId) {
|
||||
err('Ids cannot be indexed', element);
|
||||
} else {
|
||||
final isString = compositeProperty.isarType == IsarType.string ||
|
||||
compositeProperty.isarType == IsarType.stringList;
|
||||
final defaultType = compositeProperty.isarType.isList || isString
|
||||
? IndexType.hash
|
||||
: IndexType.value;
|
||||
indexProperties.add(
|
||||
ObjectIndexProperty(
|
||||
property: compositeProperty,
|
||||
type: c.type ?? defaultType,
|
||||
caseSensitive: c.caseSensitive ?? isString,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final name = index.name ??
|
||||
indexProperties.map((e) => e.property.isarName).join('_');
|
||||
checkIsarName(name, element);
|
||||
|
||||
final objectIndex = ObjectIndex(
|
||||
name: name,
|
||||
properties: indexProperties,
|
||||
unique: index.unique,
|
||||
replace: index.replace,
|
||||
);
|
||||
_verifyObjectIndex(objectIndex, element);
|
||||
|
||||
yield objectIndex;
|
||||
}
|
||||
}
|
||||
|
||||
void _verifyObjectIndex(ObjectIndex index, Element element) {
|
||||
final properties = index.properties;
|
||||
|
||||
if (properties.map((it) => it.property.isarName).distinct().length !=
|
||||
properties.length) {
|
||||
err('Composite index contains duplicate properties.', element);
|
||||
}
|
||||
|
||||
for (var i = 0; i < properties.length; i++) {
|
||||
final property = properties[i];
|
||||
if (property.isarType.isList &&
|
||||
property.type != IndexType.hash &&
|
||||
properties.length > 1) {
|
||||
err('Composite indexes do not support non-hashed lists.', element);
|
||||
}
|
||||
if (property.isarType.containsFloat && i != properties.lastIndex) {
|
||||
err(
|
||||
'Only the last property of a composite index may be a '
|
||||
'double value.',
|
||||
element,
|
||||
);
|
||||
}
|
||||
if (property.isarType == IsarType.string) {
|
||||
if (property.type != IndexType.hash && i != properties.lastIndex) {
|
||||
err(
|
||||
'Only the last property of a composite index may be a '
|
||||
'non-hashed String.',
|
||||
element,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (property.isarType.containsObject) {
|
||||
err(
|
||||
'Embedded objects may not be indexed.',
|
||||
element,
|
||||
);
|
||||
}
|
||||
if (property.type != IndexType.value) {
|
||||
if (!property.isarType.isList && property.isarType != IsarType.string) {
|
||||
err('Only Strings and Lists may be hashed.', element);
|
||||
} else if (property.isarType.containsFloat) {
|
||||
err('List<double> may must not be hashed.', element);
|
||||
}
|
||||
}
|
||||
if (property.isarType != IsarType.stringList &&
|
||||
property.type == IndexType.hashElements) {
|
||||
err('Only String lists may have hashed elements.', element);
|
||||
}
|
||||
}
|
||||
|
||||
if (!index.unique && index.replace) {
|
||||
err('Only unique indexes can replace.', element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:isar_generator/src/helper.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
const TypeChecker _dateTimeChecker = TypeChecker.fromRuntime(DateTime);
|
||||
bool _isDateTime(Element element) => _dateTimeChecker.isExactly(element);
|
||||
|
||||
extension DartTypeX on DartType {
|
||||
IsarType? get _primitiveIsarType {
|
||||
if (isDartCoreBool) {
|
||||
return IsarType.bool;
|
||||
} else if (isDartCoreInt) {
|
||||
if (alias?.element.name == 'byte') {
|
||||
return IsarType.byte;
|
||||
} else if (alias?.element.name == 'short') {
|
||||
return IsarType.int;
|
||||
} else {
|
||||
return IsarType.long;
|
||||
}
|
||||
} else if (isDartCoreDouble) {
|
||||
if (alias?.element.name == 'float') {
|
||||
return IsarType.float;
|
||||
} else {
|
||||
return IsarType.double;
|
||||
}
|
||||
} else if (isDartCoreString) {
|
||||
return IsarType.string;
|
||||
} else if (_isDateTime(element2!)) {
|
||||
return IsarType.dateTime;
|
||||
} else if (element2!.embeddedAnnotation != null) {
|
||||
return IsarType.object;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
bool get isIsarId {
|
||||
return alias?.element.name == 'Id';
|
||||
}
|
||||
|
||||
DartType get scalarType {
|
||||
if (isDartCoreList) {
|
||||
final parameterizedType = this as ParameterizedType;
|
||||
final typeArguments = parameterizedType.typeArguments;
|
||||
if (typeArguments.isNotEmpty) {
|
||||
return typeArguments[0];
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
IsarType? get isarType {
|
||||
final primitiveType = _primitiveIsarType;
|
||||
if (primitiveType != null) {
|
||||
return primitiveType;
|
||||
}
|
||||
|
||||
if (isDartCoreList) {
|
||||
switch (scalarType._primitiveIsarType) {
|
||||
case IsarType.bool:
|
||||
return IsarType.boolList;
|
||||
case IsarType.byte:
|
||||
return IsarType.byteList;
|
||||
case IsarType.int:
|
||||
return IsarType.intList;
|
||||
case IsarType.float:
|
||||
return IsarType.floatList;
|
||||
case IsarType.long:
|
||||
return IsarType.longList;
|
||||
case IsarType.double:
|
||||
return IsarType.doubleList;
|
||||
case IsarType.dateTime:
|
||||
return IsarType.dateTimeList;
|
||||
case IsarType.string:
|
||||
return IsarType.stringList;
|
||||
case IsarType.object:
|
||||
return IsarType.objectList;
|
||||
// ignore: no_default_cases
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
extension IsarTypeX on IsarType {
|
||||
bool get containsBool => this == IsarType.bool || this == IsarType.boolList;
|
||||
|
||||
bool get containsFloat =>
|
||||
this == IsarType.float ||
|
||||
this == IsarType.floatList ||
|
||||
this == IsarType.double ||
|
||||
this == IsarType.doubleList;
|
||||
|
||||
bool get containsDate =>
|
||||
this == IsarType.dateTime || this == IsarType.dateTimeList;
|
||||
|
||||
bool get containsString =>
|
||||
this == IsarType.string || this == IsarType.stringList;
|
||||
|
||||
bool get containsObject =>
|
||||
this == IsarType.object || this == IsarType.objectList;
|
||||
}
|
||||
|
|
@ -1,211 +0,0 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:dartx/dartx.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
import 'package:xxh3/xxh3.dart';
|
||||
|
||||
class ObjectInfo {
|
||||
ObjectInfo({
|
||||
required this.dartName,
|
||||
required this.isarName,
|
||||
this.accessor,
|
||||
required List<ObjectProperty> properties,
|
||||
this.embeddedDartNames = const {},
|
||||
this.indexes = const [],
|
||||
this.links = const [],
|
||||
}) {
|
||||
this.properties = properties.sortedBy((e) => e.isarName).toList();
|
||||
}
|
||||
|
||||
final String dartName;
|
||||
final String isarName;
|
||||
final String? accessor;
|
||||
late final List<ObjectProperty> properties;
|
||||
final Map<String, String> embeddedDartNames;
|
||||
final List<ObjectIndex> indexes;
|
||||
final List<ObjectLink> links;
|
||||
|
||||
int get id => xxh3(utf8.encode(isarName) as Uint8List);
|
||||
|
||||
bool get isEmbedded => accessor == null;
|
||||
|
||||
ObjectProperty get idProperty => properties.firstWhere((it) => it.isId);
|
||||
|
||||
List<ObjectProperty> get objectProperties =>
|
||||
properties.where((it) => !it.isId).toList();
|
||||
|
||||
String get getIdName => '_${dartName.decapitalize()}GetId';
|
||||
String get getLinksName => '_${dartName.decapitalize()}GetLinks';
|
||||
String get attachName => '_${dartName.decapitalize()}Attach';
|
||||
|
||||
String get estimateSizeName => '_${dartName.decapitalize()}EstimateSize';
|
||||
String get serializeName => '_${dartName.decapitalize()}Serialize';
|
||||
String get deserializeName => '_${dartName.decapitalize()}Deserialize';
|
||||
String get deserializePropName =>
|
||||
'_${dartName.decapitalize()}DeserializeProp';
|
||||
}
|
||||
|
||||
enum PropertyDeser {
|
||||
none,
|
||||
assign,
|
||||
positionalParam,
|
||||
namedParam,
|
||||
}
|
||||
|
||||
class ObjectProperty {
|
||||
ObjectProperty({
|
||||
required this.dartName,
|
||||
required this.isarName,
|
||||
required this.typeClassName,
|
||||
this.targetIsarName,
|
||||
required this.isarType,
|
||||
required this.isId,
|
||||
required this.enumMap,
|
||||
required this.enumProperty,
|
||||
required this.defaultEnumElement,
|
||||
required this.nullable,
|
||||
required this.elementNullable,
|
||||
this.userDefaultValue,
|
||||
required this.deserialize,
|
||||
required this.assignable,
|
||||
this.constructorPosition,
|
||||
});
|
||||
|
||||
final String dartName;
|
||||
final String isarName;
|
||||
final String typeClassName;
|
||||
final String? targetIsarName;
|
||||
|
||||
final bool isId;
|
||||
final IsarType isarType;
|
||||
final Map<String, dynamic>? enumMap;
|
||||
final String? enumProperty;
|
||||
final String? defaultEnumElement;
|
||||
|
||||
final bool nullable;
|
||||
final bool elementNullable;
|
||||
final String? userDefaultValue;
|
||||
|
||||
final PropertyDeser deserialize;
|
||||
final bool assignable;
|
||||
final int? constructorPosition;
|
||||
|
||||
bool get isEnum => enumMap != null;
|
||||
|
||||
String get scalarDartType {
|
||||
if (isId) {
|
||||
return 'Id';
|
||||
} else if (isEnum) {
|
||||
return typeClassName;
|
||||
}
|
||||
|
||||
switch (isarType) {
|
||||
case IsarType.bool:
|
||||
case IsarType.boolList:
|
||||
return 'bool';
|
||||
case IsarType.byte:
|
||||
case IsarType.byteList:
|
||||
case IsarType.int:
|
||||
case IsarType.intList:
|
||||
case IsarType.long:
|
||||
case IsarType.longList:
|
||||
return 'int';
|
||||
case IsarType.float:
|
||||
case IsarType.floatList:
|
||||
case IsarType.double:
|
||||
case IsarType.doubleList:
|
||||
return 'double';
|
||||
case IsarType.dateTime:
|
||||
case IsarType.dateTimeList:
|
||||
return 'DateTime';
|
||||
case IsarType.object:
|
||||
case IsarType.objectList:
|
||||
return typeClassName;
|
||||
case IsarType.string:
|
||||
case IsarType.stringList:
|
||||
return 'String';
|
||||
}
|
||||
}
|
||||
|
||||
String get nScalarDartType => isarType.isList
|
||||
? '$scalarDartType${elementNullable ? '?' : ''}'
|
||||
: '$scalarDartType${nullable ? '?' : ''}';
|
||||
|
||||
String get dartType => isarType.isList
|
||||
? 'List<$nScalarDartType>${nullable ? '?' : ''}'
|
||||
: nScalarDartType;
|
||||
|
||||
String get targetSchema => '${scalarDartType.capitalize()}Schema';
|
||||
|
||||
String enumValueMapName(ObjectInfo object) {
|
||||
return '_${object.dartName}${dartName}EnumValueMap';
|
||||
}
|
||||
|
||||
String valueEnumMapName(ObjectInfo object) {
|
||||
return '_${object.dartName}${dartName}ValueEnumMap';
|
||||
}
|
||||
}
|
||||
|
||||
class ObjectIndexProperty {
|
||||
const ObjectIndexProperty({
|
||||
required this.property,
|
||||
required this.type,
|
||||
required this.caseSensitive,
|
||||
});
|
||||
|
||||
final ObjectProperty property;
|
||||
final IndexType type;
|
||||
final bool caseSensitive;
|
||||
|
||||
IsarType get isarType => property.isarType;
|
||||
|
||||
bool get isMultiEntry => isarType.isList && type != IndexType.hash;
|
||||
}
|
||||
|
||||
class ObjectIndex {
|
||||
ObjectIndex({
|
||||
required this.name,
|
||||
required this.properties,
|
||||
required this.unique,
|
||||
required this.replace,
|
||||
});
|
||||
|
||||
final String name;
|
||||
final List<ObjectIndexProperty> properties;
|
||||
final bool unique;
|
||||
final bool replace;
|
||||
|
||||
late final id = xxh3(utf8.encode(name) as Uint8List);
|
||||
}
|
||||
|
||||
class ObjectLink {
|
||||
const ObjectLink({
|
||||
required this.dartName,
|
||||
required this.isarName,
|
||||
this.targetLinkIsarName,
|
||||
required this.targetCollectionDartName,
|
||||
required this.targetCollectionIsarName,
|
||||
required this.isSingle,
|
||||
});
|
||||
|
||||
final String dartName;
|
||||
final String isarName;
|
||||
|
||||
// isar name of the original link (only for backlinks)
|
||||
final String? targetLinkIsarName;
|
||||
final String targetCollectionDartName;
|
||||
final String targetCollectionIsarName;
|
||||
final bool isSingle;
|
||||
|
||||
bool get isBacklink => targetLinkIsarName != null;
|
||||
|
||||
int id(String objectIsarName) {
|
||||
final col = isBacklink ? targetCollectionIsarName : objectIsarName;
|
||||
final colId = xxh3(utf8.encode(col) as Uint8List, seed: isBacklink ? 1 : 0);
|
||||
|
||||
final name = targetLinkIsarName ?? isarName;
|
||||
return xxh3(utf8.encode(name) as Uint8List, seed: colId);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,533 +0,0 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
_fe_analyzer_shared:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "64.0.0"
|
||||
analyzer:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.11.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
build:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: build
|
||||
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
build_resolvers:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_resolvers
|
||||
sha256: "64e12b0521812d1684b1917bc80945625391cb9bdd4312536b1d69dcb6133ed8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
build_test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_test
|
||||
sha256: "178a9e8989cbd40b3104b88cb6ab8cbf6e3293d90b31ba44420745cba54730f1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
sha256: "595a29b55ce82d53398e1bcc2cba525d7bd7c59faeb2d2540e9d42c390cfeeeb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.6.4"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
csslib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: csslib
|
||||
sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
dart_style:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dart_style
|
||||
sha256: abd7625e16f51f554ea244d090292945ec4d4be7bfbaf2ec8cccea568919d334
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3"
|
||||
dartx:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dartx
|
||||
sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.0"
|
||||
glob:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: glob
|
||||
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: graphs
|
||||
sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: html
|
||||
sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.4"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.2"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
isar:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: isar
|
||||
sha256: "99165dadb2cf2329d3140198363a7e7bff9bbd441871898a87e26914d25cf1ea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0+1"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.7"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_annotation
|
||||
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.8.1"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
matcher:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.16"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
path:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path
|
||||
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.8.3"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.3"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
source_gen:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: source_gen
|
||||
sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.10.12"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: test
|
||||
sha256: a20ddc0723556dc6dd56094e58ec1529196d5d7774156604cb14e8445a5a82ff
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.24.7"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.1"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
sha256: "96382d0bc826e260b077bb496259e58bc82e90b603ab16cd5ae95dfe1dfcba8b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.7"
|
||||
time:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: time
|
||||
sha256: "83427e11d9072e038364a5e4da559e85869b227cf699a541be0da74f14140124"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
very_good_analysis:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: very_good_analysis
|
||||
sha256: "4815adc7ded57657038d2bb2a7f332c50e3c8152f7d3c6acf8f6b7c0cc81e5e2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: a13d5503b4facefc515c8c587ce3cf69577a7b064a9f1220e005449cf1f64aad
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.0.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
xxh3:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: xxh3
|
||||
sha256: a92b30944a9aeb4e3d4f3c3d4ddb3c7816ca73475cd603682c4f8149690f56d7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.0.0 <4.0.0"
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
name: isar_generator
|
||||
description: Code generator for the Isar Database. Finds classes annotated with @Collection.
|
||||
version: 3.1.0+1
|
||||
repository: https://github.com/isar/isar
|
||||
homepage: https://isar.dev
|
||||
|
||||
environment:
|
||||
sdk: ">=2.17.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
analyzer: ">=5.2.0 <7.0.0"
|
||||
build: ^2.3.0
|
||||
dart_style: ^2.2.3
|
||||
dartx: ^1.1.0
|
||||
glob: ^2.0.2
|
||||
isar: 3.1.0+1
|
||||
path: ^1.8.1
|
||||
source_gen: ^1.2.2
|
||||
xxh3: ^1.0.1
|
||||
|
||||
dev_dependencies:
|
||||
build_test: ^2.1.5
|
||||
matcher: ^0.12.12
|
||||
test: ^1.21.0
|
||||
very_good_analysis: ^3.0.1
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:build/build.dart';
|
||||
import 'package:build_test/build_test.dart';
|
||||
import 'package:isar_generator/isar_generator.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('Error case', () {
|
||||
for (final file in Directory('test/errors').listSync(recursive: true)) {
|
||||
if (file is! File || !file.path.endsWith('.dart')) continue;
|
||||
|
||||
test(file.path, () async {
|
||||
final content = await file.readAsLines();
|
||||
|
||||
final errorMessage = content.first.split('//').last.trim();
|
||||
|
||||
var error = '';
|
||||
try {
|
||||
await testBuilder(
|
||||
getIsarGenerator(BuilderOptions.empty),
|
||||
{'a|${file.path}': content.join('\n')},
|
||||
reader: await PackageAssetReader.currentIsolate(),
|
||||
);
|
||||
} catch (e) {
|
||||
error = e.toString();
|
||||
}
|
||||
|
||||
expect(error.toLowerCase(), contains(errorMessage.toLowerCase()));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
// must not be abstract
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
abstract class Model {
|
||||
Id? id;
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// supertype annotated with @collection
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Supertype {
|
||||
Id? id;
|
||||
}
|
||||
|
||||
class Subtype implements Supertype {
|
||||
@override
|
||||
Id? id;
|
||||
}
|
||||
|
||||
@collection
|
||||
class Model implements Subtype {
|
||||
@override
|
||||
Id? id;
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// unnamed constructor
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Model.create();
|
||||
|
||||
Id? id;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// constructor parameter does not match a property
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
// ignore: avoid_unused_constructor_parameters
|
||||
Model(this.prop1, String somethingElse);
|
||||
|
||||
Id? id;
|
||||
|
||||
final String prop1;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// constructor parameter type does not match property type
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
// ignore: avoid_unused_constructor_parameters
|
||||
Model(int prop1);
|
||||
|
||||
Id? id;
|
||||
|
||||
String prop1 = '5';
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
// only classes
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
// ignore: invalid_annotation_target
|
||||
@collection
|
||||
enum Test { a, b, c }
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
// must not be abstract
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
abstract class Model {
|
||||
Id? id;
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
// only classes
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
// ignore: invalid_annotation_target
|
||||
@collection
|
||||
mixin Test {}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
// must be public
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
// ignore: unused_element
|
||||
class _Model {
|
||||
Id? id;
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
// only classes
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
// ignore: invalid_annotation_target
|
||||
@collection
|
||||
const t = 'hello';
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// two or more properties with type "Id" defined
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Test {
|
||||
Id? id1;
|
||||
|
||||
Id? id2;
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// no id property defined
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Test {
|
||||
late int id;
|
||||
|
||||
late String name;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// only the last property of a composite index may be a double value
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(composite: [CompositeIndex('val2')])
|
||||
double? val1;
|
||||
|
||||
String? val2;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// composite indexes do not support non-hashed lists
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(composite: [CompositeIndex('str')], type: IndexType.value)
|
||||
List<int>? list;
|
||||
|
||||
String? str;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// last property of a composite index may be a non-hashed string
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(composite: [CompositeIndex('str2')], type: IndexType.value)
|
||||
String? str1;
|
||||
|
||||
String? str2;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// ids cannot be indexed
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(composite: [CompositeIndex('id')])
|
||||
String? str;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// list<double> may must not be hashed
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(type: IndexType.hash)
|
||||
List<double>? list;
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
// same name
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(name: 'myindex')
|
||||
String? prop1;
|
||||
|
||||
@Index(name: 'myindex')
|
||||
String? prop2;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// composite index contains duplicate properties
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(composite: [CompositeIndex('str1')], type: IndexType.value)
|
||||
String? str1;
|
||||
|
||||
String? str2;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// names must not be blank or start with "_"
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(name: '_index')
|
||||
String? str;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// only strings and lists may be hashed
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(type: IndexType.hash)
|
||||
int? val;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// only string lists may have hashed elements
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(type: IndexType.hashElements)
|
||||
List<int>? list;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// only unique indexes can replace
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(replace: true)
|
||||
String? str;
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
// objects may not be indexed
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index()
|
||||
EmbeddedModel? obj;
|
||||
}
|
||||
|
||||
@embedded
|
||||
class EmbeddedModel {}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
// objects may not be indexed
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(type: IndexType.hash)
|
||||
List<EmbeddedModel>? list;
|
||||
}
|
||||
|
||||
@embedded
|
||||
class EmbeddedModel {}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// property does not exist
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Index(composite: [CompositeIndex('myProp')])
|
||||
String? str;
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
// target of backlink does not exist
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model1 {
|
||||
Id? id;
|
||||
|
||||
@Backlink(to: 'abc')
|
||||
final IsarLink<Model2> link = IsarLink();
|
||||
}
|
||||
|
||||
@collection
|
||||
class Model2 {
|
||||
Id? id;
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// target of backlink is also a backlink
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model1 {
|
||||
Id? id;
|
||||
|
||||
@Backlink(to: 'link')
|
||||
final IsarLink<Model2> link = IsarLink();
|
||||
}
|
||||
|
||||
@collection
|
||||
class Model2 {
|
||||
Id? id;
|
||||
|
||||
@Backlink(to: 'link')
|
||||
final IsarLink<Model1> link = IsarLink();
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// target of backlink is not a link
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model1 {
|
||||
Id? id;
|
||||
|
||||
@Backlink(to: 'str')
|
||||
final IsarLink<Model2> link = IsarLink();
|
||||
}
|
||||
|
||||
@collection
|
||||
class Model2 {
|
||||
Id? id;
|
||||
|
||||
String? str;
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// same name
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
final IsarLink<Model2> prop1 = IsarLink();
|
||||
|
||||
@Name('prop1')
|
||||
final IsarLinks<Model2> prop2 = IsarLinks();
|
||||
}
|
||||
|
||||
@collection
|
||||
class Model2 {
|
||||
Id? id;
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
// names must not be blank or start with
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Name('_link')
|
||||
final IsarLink<Model2> link = IsarLink();
|
||||
}
|
||||
|
||||
@collection
|
||||
class Model2 {
|
||||
Id? id;
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// must not be late
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
late IsarLink<Model2> link;
|
||||
}
|
||||
|
||||
@collection
|
||||
class Model2 {
|
||||
Id? id;
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// must not be nullable
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
IsarLink<Model2>? link;
|
||||
}
|
||||
|
||||
@collection
|
||||
class Model2 {
|
||||
Id? id;
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// link target is not annotated with @collection
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
final IsarLink<int> link = IsarLink();
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// links type must not be nullable
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
final IsarLink<Model2?> link = IsarLink();
|
||||
}
|
||||
|
||||
@collection
|
||||
class Model2 {
|
||||
Id? id;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// same name
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
String? prop1;
|
||||
|
||||
@Name('prop1')
|
||||
String? prop2;
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// unsupported enum property type
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Enumerated(EnumType.value, 'value')
|
||||
late MyEnum field;
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
optionA;
|
||||
|
||||
final bool value = true;
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// unsupported enum property type
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Enumerated(EnumType.value, 'value')
|
||||
late MyEnum field;
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
optionA;
|
||||
|
||||
final double value = 5.5;
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
// has duplicate values
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Enumerated(EnumType.value, 'value')
|
||||
late MyEnum field;
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
option1(1),
|
||||
option2(2),
|
||||
option3(1);
|
||||
|
||||
const MyEnum(this.value);
|
||||
|
||||
final int value;
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// unsupported enum property type
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Enumerated(EnumType.value, 'value')
|
||||
late MyEnum field;
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
optionA;
|
||||
|
||||
final float value = 5.5;
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// unsupported enum property type
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Enumerated(EnumType.value, 'value')
|
||||
late MyEnum prop;
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
optionA;
|
||||
|
||||
final List<String> value = [];
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
// enum property must be annotated with @enumerated
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
late MyEnum? prop;
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
a;
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// null values are not supported
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Enumerated(EnumType.value, 'value')
|
||||
late MyEnum prop;
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
optionA;
|
||||
|
||||
final String? value = null;
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
// unsupported enum property type
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Enumerated(EnumType.value, 'value')
|
||||
late MyEnum prop;
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
optionA;
|
||||
|
||||
final value = EmbeddedModel();
|
||||
}
|
||||
|
||||
@embedded
|
||||
class EmbeddedModel {}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
// names must not be blank or start with "_"
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
@Name('_prop')
|
||||
String? prop;
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// bytes must not be nullable
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
late byte? prop;
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// bytes must not be nullable
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
late List<byte?> prop;
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// unsupported type
|
||||
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
@collection
|
||||
class Model {
|
||||
Id? id;
|
||||
|
||||
late Set<String>? prop;
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ packages:
|
|||
source: hosted
|
||||
version: "64.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
|
||||
|
|
@ -697,9 +697,10 @@ packages:
|
|||
isar_generator:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
path: "packages/isar_generator"
|
||||
relative: true
|
||||
source: path
|
||||
name: isar_generator
|
||||
sha256: "76c121e1295a30423604f2f819bc255bc79f852f3bc8743a24017df6068ad133"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0+1"
|
||||
js:
|
||||
dependency: transitive
|
||||
|
|
|
|||
|
|
@ -58,10 +58,11 @@ dependencies:
|
|||
crypto: ^3.0.3
|
||||
rinf: ^4.13.1
|
||||
protobuf: ^3.1.0
|
||||
cupertino_icons: ^1.0.2
|
||||
|
||||
|
||||
|
||||
cupertino_icons: ^1.0.2
|
||||
dependency_overrides:
|
||||
analyzer: ">=5.2.0 <7.0.0"
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
@ -69,8 +70,7 @@ dev_dependencies:
|
|||
build_runner: ^2.4.6
|
||||
riverpod_generator: ^2.3.2
|
||||
flutter_launcher_icons: ^0.13.1
|
||||
isar_generator:
|
||||
path: ./packages/isar_generator
|
||||
isar_generator: ^3.1.0+1
|
||||
flutter_lints: ^2.0.1
|
||||
|
||||
flutter:
|
||||
|
|
|
|||
Loading…
Reference in a new issue