Migrated angel_orm

This commit is contained in:
thomashii@dukefirehawk.com 2021-05-02 15:32:24 +08:00
parent ed87d48c96
commit 69b7483794
38 changed files with 278 additions and 681 deletions

View file

@ -38,6 +38,11 @@
* Updated angel_orm_test to 1.0.0 (in progress) * Updated angel_orm_test to 1.0.0 (in progress)
* Updated angel_orm_postgres to 2.0.0 (in progress) * Updated angel_orm_postgres to 2.0.0 (in progress)
* Update orm-sdk-2.12.x boilerplate (in progress) * Update orm-sdk-2.12.x boilerplate (in progress)
* Updated angel_serialize to 4.0.0 (0/0 tests passed)
* Updated angel_serialize_generator to 4.0.0 (33/33 tests passed)
* Updated angel_orm to 4.0.0 (0/0 tests passed)
* Updated angel_migration to 3.0.0
* Updated angel_orm_generator to 3.0.0 (use a fork of postgres)
# 3.0.0 (Non NNBD) # 3.0.0 (Non NNBD)
* Changed Dart SDK requirements for all packages to ">=2.10.0 <3.0.0" * Changed Dart SDK requirements for all packages to ">=2.10.0 <3.0.0"
@ -65,7 +70,7 @@
* Update basic-sdk-2.12.x boilerplate (1/1 tests passed) * Update basic-sdk-2.12.x boilerplate (1/1 tests passed)
* Updated angel_serialize to 3.0.0 (0/0 tests passed) * Updated angel_serialize to 3.0.0 (0/0 tests passed)
* Updated angel_serialize_generator to 3.0.0 (33/33 tests passed) * Updated angel_serialize_generator to 3.0.0 (33/33 tests passed)
* Updated angel_orm to 3.0.0 * Updated angel_orm to 3.0.0 (0/0 tests passed)
* Updated angel_migration to 3.0.0 * Updated angel_migration to 3.0.0
* Updated angel_orm_generator to 3.0.0 (use a fork of postgres) * Updated angel_orm_generator to 3.0.0 (use a fork of postgres)
* Updated angel_migration_runner to 3.0.0 * Updated angel_migration_runner to 3.0.0

View file

@ -38,8 +38,8 @@ main() async {
'http://localhost:3000/auth/twitter/callback', 'http://localhost:3000/auth/twitter/callback',
), ),
(twit, req, res) async { (twit, req, res) async {
var response = await twit.twitterClient var response = await twit.twitterClient.get(Uri.parse(
.get('https://api.twitter.com/1.1/account/verify_credentials.json'); 'https://api.twitter.com/1.1/account/verify_credentials.json'));
var userData = json.decode(response.body) as Map; var userData = json.decode(response.body) as Map;
return _User(userData['screen_name'] as String); return _User(userData['screen_name'] as String);
}, },

View file

@ -1,11 +1,10 @@
name: "angel_auth_twitter" name: "angel_auth_twitter"
#author: "Tobe O <thosakwe@gmail.com>" version: 3.0.0
description: "package:angel_auth strategy for Twitter login. Auto-signs requests." description: "package:angel_auth strategy for Twitter login. Auto-signs requests."
homepage: "https://github.com/angel-dart/auth_twitter.git"
publish_to: none
environment: environment:
sdk: ">=2.10.0 <3.0.0" sdk: ">=2.10.0 <3.0.0"
homepage: "https://github.com/angel-dart/auth_twitter.git"
version: 3.0.0
publish_to: none
dependencies: dependencies:
angel_auth: angel_auth:
git: git:

View file

@ -1 +0,0 @@
orm

View file

@ -1,451 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DBNavigator.Project.DataEditorManager">
<record-view-column-sorting-type value="BY_INDEX" />
<value-preview-text-wrapping value="true" />
<value-preview-pinned value="false" />
</component>
<component name="DBNavigator.Project.DataExportManager">
<export-instructions>
<create-header value="true" />
<quote-values-containing-separator value="true" />
<quote-all-values value="false" />
<value-separator value="" />
<file-name value="" />
<file-location value="" />
<scope value="GLOBAL" />
<destination value="FILE" />
<format value="EXCEL" />
<charset value="windows-1252" />
</export-instructions>
</component>
<component name="DBNavigator.Project.DatabaseBrowserManager">
<autoscroll-to-editor value="false" />
<autoscroll-from-editor value="true" />
<show-object-properties value="true" />
<loaded-nodes />
</component>
<component name="DBNavigator.Project.EditorStateManager">
<last-used-providers />
</component>
<component name="DBNavigator.Project.MethodExecutionManager">
<method-browser />
<execution-history>
<group-entries value="true" />
<execution-inputs />
</execution-history>
<argument-values-cache />
</component>
<component name="DBNavigator.Project.ObjectDependencyManager">
<last-used-dependency-type value="INCOMING" />
</component>
<component name="DBNavigator.Project.ObjectQuickFilterManager">
<last-used-operator value="EQUAL" />
<filters />
</component>
<component name="DBNavigator.Project.ScriptExecutionManager" clear-outputs="true">
<recently-used-interfaces />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<browser-settings>
<general>
<display-mode value="TABBED" />
<navigation-history-size value="100" />
<show-object-details value="false" />
</general>
<filters>
<object-type-filter>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="true" />
<object-type name="ROLE" enabled="true" />
<object-type name="PRIVILEGE" enabled="true" />
<object-type name="CHARSET" enabled="true" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED_VIEW" enabled="true" />
<object-type name="NESTED_TABLE" enabled="true" />
<object-type name="COLUMN" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET_TRIGGER" enabled="true" />
<object-type name="DATABASE_TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="true" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
<object-type name="ARGUMENT" enabled="true" />
<object-type name="DIMENSION" enabled="true" />
<object-type name="CLUSTER" enabled="true" />
<object-type name="DBLINK" enabled="true" />
</object-type-filter>
</filters>
<sorting>
<object-type name="COLUMN" sorting-type="NAME" />
<object-type name="FUNCTION" sorting-type="NAME" />
<object-type name="PROCEDURE" sorting-type="NAME" />
<object-type name="ARGUMENT" sorting-type="POSITION" />
</sorting>
<default-editors>
<object-type name="VIEW" editor-type="SELECTION" />
<object-type name="PACKAGE" editor-type="SELECTION" />
<object-type name="TYPE" editor-type="SELECTION" />
</default-editors>
</browser-settings>
<navigation-settings>
<lookup-filters>
<lookup-objects>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="false" />
<object-type name="ROLE" enabled="false" />
<object-type name="PRIVILEGE" enabled="false" />
<object-type name="CHARSET" enabled="false" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED VIEW" enabled="true" />
<object-type name="NESTED TABLE" enabled="false" />
<object-type name="COLUMN" enabled="false" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET TRIGGER" enabled="true" />
<object-type name="DATABASE TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="false" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE ATTRIBUTE" enabled="false" />
<object-type name="ARGUMENT" enabled="false" />
<object-type name="DIMENSION" enabled="false" />
<object-type name="CLUSTER" enabled="false" />
<object-type name="DBLINK" enabled="true" />
</lookup-objects>
<force-database-load value="false" />
<prompt-connection-selection value="true" />
<prompt-schema-selection value="true" />
</lookup-filters>
</navigation-settings>
<dataset-grid-settings>
<general>
<enable-zooming value="true" />
</general>
<sorting>
<nulls-first value="true" />
<max-sorting-columns value="4" />
</sorting>
<tracking-columns>
<columnNames value="" />
<visible value="true" />
<editable value="false" />
</tracking-columns>
</dataset-grid-settings>
<dataset-editor-settings>
<text-editor-popup>
<active value="false" />
<active-if-empty value="false" />
<data-length-threshold value="100" />
<popup-delay value="1000" />
</text-editor-popup>
<values-list-popup>
<show-popup-button value="true" />
<element-count-threshold value="1000" />
<data-length-threshold value="250" />
</values-list-popup>
<general>
<fetch-block-size value="100" />
<fetch-timeout value="30" />
<trim-whitespaces value="true" />
<convert-empty-strings-to-null value="true" />
<select-content-on-cell-edit value="true" />
<large-value-preview-active value="true" />
</general>
<filters>
<prompt-filter-dialog value="true" />
<default-filter-type value="BASIC" />
</filters>
<qualified-text-editor text-length-threshold="300">
<content-types>
<content-type name="Text" enabled="true" />
<content-type name="XML" enabled="true" />
<content-type name="DTD" enabled="true" />
<content-type name="HTML" enabled="true" />
<content-type name="XHTML" enabled="true" />
<content-type name="CSS" enabled="true" />
<content-type name="SQL" enabled="true" />
<content-type name="PL/SQL" enabled="true" />
<content-type name="JavaScript" enabled="true" />
<content-type name="JSP" enabled="true" />
<content-type name="JSPx" enabled="true" />
<content-type name="ASP" enabled="true" />
<content-type name="YAML" enabled="true" />
<content-type name="Bash" enabled="true" />
</content-types>
</qualified-text-editor>
<record-navigation>
<navigation-target value="VIEWER" />
</record-navigation>
</dataset-editor-settings>
<code-editor-settings>
<general>
<show-object-navigation-gutter value="false" />
<show-spec-declaration-navigation-gutter value="true" />
</general>
<confirmations>
<save-changes value="false" />
<revert-changes value="true" />
</confirmations>
</code-editor-settings>
<code-completion-settings>
<filters>
<basic-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="false" />
<filter-element type="OBJECT" id="view" selected="false" />
<filter-element type="OBJECT" id="materialized view" selected="false" />
<filter-element type="OBJECT" id="index" selected="false" />
<filter-element type="OBJECT" id="constraint" selected="false" />
<filter-element type="OBJECT" id="trigger" selected="false" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="false" />
<filter-element type="OBJECT" id="procedure" selected="false" />
<filter-element type="OBJECT" id="function" selected="false" />
<filter-element type="OBJECT" id="package" selected="false" />
<filter-element type="OBJECT" id="type" selected="false" />
<filter-element type="OBJECT" id="dimension" selected="false" />
<filter-element type="OBJECT" id="cluster" selected="false" />
<filter-element type="OBJECT" id="dblink" selected="false" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</basic-filter>
<extended-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</extended-filter>
</filters>
<sorting enabled="true">
<sorting-element type="RESERVED_WORD" id="keyword" />
<sorting-element type="RESERVED_WORD" id="datatype" />
<sorting-element type="OBJECT" id="column" />
<sorting-element type="OBJECT" id="table" />
<sorting-element type="OBJECT" id="view" />
<sorting-element type="OBJECT" id="materialized view" />
<sorting-element type="OBJECT" id="index" />
<sorting-element type="OBJECT" id="constraint" />
<sorting-element type="OBJECT" id="trigger" />
<sorting-element type="OBJECT" id="synonym" />
<sorting-element type="OBJECT" id="sequence" />
<sorting-element type="OBJECT" id="procedure" />
<sorting-element type="OBJECT" id="function" />
<sorting-element type="OBJECT" id="package" />
<sorting-element type="OBJECT" id="type" />
<sorting-element type="OBJECT" id="dimension" />
<sorting-element type="OBJECT" id="cluster" />
<sorting-element type="OBJECT" id="dblink" />
<sorting-element type="OBJECT" id="schema" />
<sorting-element type="OBJECT" id="role" />
<sorting-element type="OBJECT" id="user" />
<sorting-element type="RESERVED_WORD" id="function" />
<sorting-element type="RESERVED_WORD" id="parameter" />
</sorting>
<format>
<enforce-code-style-case value="true" />
</format>
</code-completion-settings>
<execution-engine-settings>
<statement-execution>
<fetch-block-size value="100" />
<execution-timeout value="20" />
<debug-execution-timeout value="600" />
<focus-result value="false" />
<prompt-execution value="false" />
</statement-execution>
<script-execution>
<command-line-interfaces />
<execution-timeout value="300" />
</script-execution>
<method-execution>
<execution-timeout value="30" />
<debug-execution-timeout value="600" />
<parameter-history-size value="10" />
</method-execution>
</execution-engine-settings>
<operation-settings>
<transactions>
<uncommitted-changes>
<on-project-close value="ASK" />
<on-disconnect value="ASK" />
<on-autocommit-toggle value="ASK" />
</uncommitted-changes>
<multiple-uncommitted-changes>
<on-commit value="ASK" />
<on-rollback value="ASK" />
</multiple-uncommitted-changes>
</transactions>
<session-browser>
<disconnect-session value="ASK" />
<kill-session value="ASK" />
<reload-on-filter-change value="false" />
</session-browser>
<compiler>
<compile-type value="KEEP" />
<compile-dependencies value="ASK" />
<always-show-controls value="false" />
</compiler>
<debugger>
<debugger-type value="JDBC" />
<use-generic-runners value="true" />
</debugger>
</operation-settings>
<ddl-file-settings>
<extensions>
<mapping file-type-id="VIEW" extensions="vw" />
<mapping file-type-id="TRIGGER" extensions="trg" />
<mapping file-type-id="PROCEDURE" extensions="prc" />
<mapping file-type-id="FUNCTION" extensions="fnc" />
<mapping file-type-id="PACKAGE" extensions="pkg" />
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
<mapping file-type-id="TYPE" extensions="tpe" />
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
</extensions>
<general>
<lookup-ddl-files value="true" />
<create-ddl-files value="false" />
<synchronize-ddl-files value="true" />
<use-qualified-names value="false" />
<make-scripts-rerunnable value="true" />
</general>
</ddl-file-settings>
<general-settings>
<regional-settings>
<date-format value="MEDIUM" />
<number-format value="UNGROUPED" />
<locale value="SYSTEM_DEFAULT" />
<use-custom-formats value="false" />
</regional-settings>
<environment>
<environment-types>
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
</environment-types>
<visibility-settings>
<connection-tabs value="true" />
<dialog-headers value="true" />
<object-editor-tabs value="true" />
<script-editor-tabs value="false" />
<execution-result-tabs value="true" />
</visibility-settings>
</environment>
</general-settings>
</component>
<component name="DBNavigator.Project.StatementExecutionManager">
<execution-variables />
</component>
</project>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/orm.iml" filepath="$PROJECT_DIR$/.idea/orm.iml" />
</modules>
</component>
</project>

View file

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$/angel_orm">
<excludeFolder url="file://$MODULE_DIR$/angel_orm/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/angel_orm/.pub" />
<excludeFolder url="file://$MODULE_DIR$/angel_orm/build" />
</content>
<content url="file://$MODULE_DIR$/angel_orm_generator">
<excludeFolder url="file://$MODULE_DIR$/angel_orm_generator/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/angel_orm_generator/.pub" />
<excludeFolder url="file://$MODULE_DIR$/angel_orm_generator/build" />
</content>
<content url="file://$MODULE_DIR$/external">
<excludeFolder url="file://$MODULE_DIR$/external/.pub" />
<excludeFolder url="file://$MODULE_DIR$/external/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>

View file

@ -1,6 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="tests in has_one_test" type="DartTestRunConfigurationType" factoryName="Dart Test" folderName="leg" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/angel_orm_generator/test/has_one_test.dart" />
<method />
</configuration>
</component>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View file

@ -0,0 +1,2 @@
Tobe O <thosakwe@gmail.com>
Thomas Hii <thomashii@dukefirehawk.com>

View file

@ -1,3 +1,9 @@
# 4.0.0
* Migrated to support Dart SDK 2.12.x NNBD
# 3.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
# 2.0.0 # 2.0.0
* Bump to `2.0.0`. * Bump to `2.0.0`.

View file

@ -0,0 +1,2 @@
Tobe O <thosakwe@gmail.com>
Thomas Hii <thomashii@dukefirehawk.com>

View file

@ -1,3 +1,9 @@
# 4.0.0
* Migrated to support Dart SDK 2.12.x NNBD
# 3.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
# 2.0.0 # 2.0.0
* Bump to `2.0.0`. * Bump to `2.0.0`.

View file

@ -0,0 +1,2 @@
Tobe O <thosakwe@gmail.com>
Thomas Hii <thomashii@dukefirehawk.com>

View file

@ -1,3 +1,9 @@
# 4.0.0
* Migrated to support Dart SDK 2.12.x NNBD
# 3.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
# 2.1.0-beta.3 # 2.1.0-beta.3
* Remove parentheses from `AS` when renaming raw `expressions`. * Remove parentheses from `AS` when renaming raw `expressions`.

View file

@ -7,15 +7,15 @@ import 'package:angel_serialize/angel_serialize.dart';
part 'main.g.dart'; part 'main.g.dart';
part 'main.serializer.g.dart'; part 'main.serializer.g.dart';
main() async { void main() async {
var query = EmployeeQuery() var query = EmployeeQuery()
..where.firstName.equals('Rich') ..where?.firstName.equals('Rich')
..where.lastName.equals('Person') ..where?.lastName.equals('Person')
..orWhere((w) => w.salary.greaterThanOrEqualTo(75000)) ..orWhere((w) => w?.salary.greaterThanOrEqualTo(75000))
..join('companies', 'company_id', 'id'); ..join('companies', 'company_id', 'id');
var richPerson = await query.getOne(_FakeExecutor()); var richPerson = await query.getOne(_FakeExecutor());
print(richPerson.toJson()); print(richPerson?.toJson());
} }
class _FakeExecutor extends QueryExecutor { class _FakeExecutor extends QueryExecutor {
@ -23,7 +23,7 @@ class _FakeExecutor extends QueryExecutor {
@override @override
Future<List<List>> query( Future<List<List>> query(
String tableName, String query, Map<String, dynamic> substitutionValues, String tableName, String? query, Map<String, dynamic> substitutionValues,
[returningFields]) async { [returningFields]) async {
var now = DateTime.now(); var now = DateTime.now();
print( print(
@ -42,25 +42,25 @@ class _FakeExecutor extends QueryExecutor {
@orm @orm
@serializable @serializable
abstract class _Employee extends Model { abstract class _Employee extends Model {
String get firstName; String? get firstName;
String get lastName; String? get lastName;
double get salary; double? get salary;
} }
class EmployeeQuery extends Query<Employee, EmployeeQueryWhere> { class EmployeeQuery extends Query<Employee, EmployeeQueryWhere?> {
@override @override
final QueryValues values = MapQueryValues(); final QueryValues values = MapQueryValues();
EmployeeQueryWhere _where; EmployeeQueryWhere? _where;
EmployeeQuery() { EmployeeQuery() {
_where = EmployeeQueryWhere(this); _where = EmployeeQueryWhere(this);
} }
@override @override
EmployeeQueryWhere get where => _where; EmployeeQueryWhere? get where => _where;
@override @override
String get tableName => 'employees'; String get tableName => 'employees';

View file

@ -17,30 +17,30 @@ class Employee extends _Employee {
this.updatedAt}); this.updatedAt});
@override @override
final String id; final String? id;
@override @override
final String firstName; final String? firstName;
@override @override
final String lastName; final String? lastName;
@override @override
final double salary; final double? salary;
@override @override
final DateTime createdAt; final DateTime? createdAt;
@override @override
final DateTime updatedAt; final DateTime? updatedAt;
Employee copyWith( Employee copyWith(
{String id, {String? id,
String firstName, String? firstName,
String lastName, String? lastName,
double salary, double? salary,
DateTime createdAt, DateTime? createdAt,
DateTime updatedAt}) { DateTime? updatedAt}) {
return Employee( return Employee(
id: id ?? this.id, id: id ?? this.id,
firstName: firstName ?? this.firstName, firstName: firstName ?? this.firstName,

View file

@ -9,26 +9,23 @@ part of 'main.dart';
abstract class EmployeeSerializer { abstract class EmployeeSerializer {
static Employee fromMap(Map map) { static Employee fromMap(Map map) {
return Employee( return Employee(
id: map['id'] as String, id: map['id'] as String?,
firstName: map['first_name'] as String, firstName: map['first_name'] as String?,
lastName: map['last_name'] as String, lastName: map['last_name'] as String?,
salary: map['salary'] as double, salary: map['salary'] as double?,
createdAt: map['created_at'] != null createdAt: map['created_at'] != null
? (map['created_at'] is DateTime ? (map['created_at'] is DateTime
? (map['created_at'] as DateTime) ? (map['created_at'] as DateTime?)
: DateTime.parse(map['created_at'].toString())) : DateTime.parse(map['created_at'].toString()))
: null, : null,
updatedAt: map['updated_at'] != null updatedAt: map['updated_at'] != null
? (map['updated_at'] is DateTime ? (map['updated_at'] is DateTime
? (map['updated_at'] as DateTime) ? (map['updated_at'] as DateTime?)
: DateTime.parse(map['updated_at'].toString())) : DateTime.parse(map['updated_at'].toString()))
: null); : null);
} }
static Map<String, dynamic> toMap(Employee model) { static Map<String, dynamic> toMap(Employee model) {
if (model == null) {
return null;
}
return { return {
'id': model.id, 'id': model.id,
'first_name': model.firstName, 'first_name': model.firstName,

View file

@ -17,7 +17,7 @@ class Orm {
/// The name of the table to query. /// The name of the table to query.
/// ///
/// Inferred if not present. /// Inferred if not present.
final String tableName; final String? tableName;
/// Whether to generate migrations for this model. /// Whether to generate migrations for this model.
/// ///

View file

@ -8,9 +8,9 @@ final DateFormat dateYmdHms = DateFormat('yyyy-MM-dd HH:mm:ss');
abstract class SqlExpressionBuilder<T> { abstract class SqlExpressionBuilder<T> {
final Query query; final Query query;
final String columnName; final String columnName;
String _cast; String? _cast;
bool _isProperty = false; bool _isProperty = false;
String _substitution; String? _substitution;
SqlExpressionBuilder(this.query, this.columnName); SqlExpressionBuilder(this.query, this.columnName);
@ -21,15 +21,15 @@ abstract class SqlExpressionBuilder<T> {
bool get hasValue; bool get hasValue;
String compile(); String? compile();
} }
class NumericSqlExpressionBuilder<T extends num> class NumericSqlExpressionBuilder<T extends num>
extends SqlExpressionBuilder<T> { extends SqlExpressionBuilder<T> {
bool _hasValue = false; bool _hasValue = false;
String _op = '='; String _op = '=';
String _raw; String? _raw;
T _value; T? _value;
NumericSqlExpressionBuilder(Query query, String columnName) NumericSqlExpressionBuilder(Query query, String columnName)
: super(query, columnName); : super(query, columnName);
@ -45,7 +45,7 @@ class NumericSqlExpressionBuilder<T extends num>
} }
@override @override
String compile() { String? compile() {
if (_raw != null) return _raw; if (_raw != null) return _raw;
if (_value == null) return null; if (_value == null) return null;
var v = _value.toString(); var v = _value.toString();
@ -121,8 +121,8 @@ class EnumSqlExpressionBuilder<T> extends SqlExpressionBuilder<T> {
final int Function(T) _getValue; final int Function(T) _getValue;
bool _hasValue = false; bool _hasValue = false;
String _op = '='; String _op = '=';
String _raw; String? _raw;
int _value; int? _value;
EnumSqlExpressionBuilder(Query query, String columnName, this._getValue) EnumSqlExpressionBuilder(Query query, String columnName, this._getValue)
: super(query, columnName); : super(query, columnName);
@ -141,7 +141,7 @@ class EnumSqlExpressionBuilder<T> extends SqlExpressionBuilder<T> {
UnsupportedError('Enums do not support this operation.'); UnsupportedError('Enums do not support this operation.');
@override @override
String compile() { String? compile() {
if (_raw != null) return _raw; if (_raw != null) return _raw;
if (_value == null) return null; if (_value == null) return null;
return '$_op $_value'; return '$_op $_value';
@ -182,7 +182,7 @@ class EnumSqlExpressionBuilder<T> extends SqlExpressionBuilder<T> {
class StringSqlExpressionBuilder extends SqlExpressionBuilder<String> { class StringSqlExpressionBuilder extends SqlExpressionBuilder<String> {
bool _hasValue = false; bool _hasValue = false;
String _op = '=', _raw, _value; String? _op = '=', _raw, _value;
StringSqlExpressionBuilder(Query query, String columnName) StringSqlExpressionBuilder(Query query, String columnName)
: super(query, columnName); : super(query, columnName);
@ -203,7 +203,7 @@ class StringSqlExpressionBuilder extends SqlExpressionBuilder<String> {
} }
@override @override
String compile() { String? compile() {
if (_raw != null) return _raw; if (_raw != null) return _raw;
if (_value == null) return null; if (_value == null) return null;
return "$_op @$substitution"; return "$_op @$substitution";
@ -232,7 +232,7 @@ class StringSqlExpressionBuilder extends SqlExpressionBuilder<String> {
/// carNameBuilder.like('%Mazda%'); /// carNameBuilder.like('%Mazda%');
/// carNameBuilder.like((name) => 'Mazda %$name%'); /// carNameBuilder.like((name) => 'Mazda %$name%');
/// ``` /// ```
void like(String pattern, {String Function(String) sanitize}) { void like(String pattern, {String Function(String)? sanitize}) {
sanitize ??= (s) => pattern; sanitize ??= (s) => pattern;
_raw = 'LIKE \'' + sanitize('@$substitution') + '\''; _raw = 'LIKE \'' + sanitize('@$substitution') + '\'';
query.substitutionValues[substitution] = pattern; query.substitutionValues[substitution] = pattern;
@ -287,8 +287,8 @@ class StringSqlExpressionBuilder extends SqlExpressionBuilder<String> {
class BooleanSqlExpressionBuilder extends SqlExpressionBuilder<bool> { class BooleanSqlExpressionBuilder extends SqlExpressionBuilder<bool> {
bool _hasValue = false; bool _hasValue = false;
String _op = '=', _raw; String? _op = '=', _raw;
bool _value; bool? _value;
BooleanSqlExpressionBuilder(Query query, String columnName) BooleanSqlExpressionBuilder(Query query, String columnName)
: super(query, columnName); : super(query, columnName);
@ -304,10 +304,10 @@ class BooleanSqlExpressionBuilder extends SqlExpressionBuilder<bool> {
} }
@override @override
String compile() { String? compile() {
if (_raw != null) return _raw; if (_raw != null) return _raw;
if (_value == null) return null; if (_value == null) return null;
var v = _value ? 'TRUE' : 'FALSE'; var v = _value! ? 'TRUE' : 'FALSE';
if (_cast != null) v = 'CAST ($v AS $_cast)'; if (_cast != null) v = 'CAST ($v AS $_cast)';
return '$_op $v'; return '$_op $v';
} }
@ -336,9 +336,14 @@ class BooleanSqlExpressionBuilder extends SqlExpressionBuilder<bool> {
} }
class DateTimeSqlExpressionBuilder extends SqlExpressionBuilder<DateTime> { class DateTimeSqlExpressionBuilder extends SqlExpressionBuilder<DateTime> {
NumericSqlExpressionBuilder<int> _year, _month, _day, _hour, _minute, _second; NumericSqlExpressionBuilder<int>? _year,
_month,
_day,
_hour,
_minute,
_second;
String _raw; String? _raw;
DateTimeSqlExpressionBuilder(Query query, String columnName) DateTimeSqlExpressionBuilder(Query query, String columnName)
: super(query, columnName); : super(query, columnName);
@ -431,25 +436,25 @@ class DateTimeSqlExpressionBuilder extends SqlExpressionBuilder<DateTime> {
} }
@override @override
String compile() { String? compile() {
if (_raw?.isNotEmpty == true) return _raw; if (_raw?.isNotEmpty == true) return _raw;
List<String> parts = []; var parts = <String>[];
if (year?.hasValue == true) { if (year.hasValue == true) {
parts.add('YEAR($columnName) ${year.compile()}'); parts.add('YEAR($columnName) ${year.compile()}');
} }
if (month?.hasValue == true) { if (month.hasValue == true) {
parts.add('MONTH($columnName) ${month.compile()}'); parts.add('MONTH($columnName) ${month.compile()}');
} }
if (day?.hasValue == true) { if (day.hasValue == true) {
parts.add('DAY($columnName) ${day.compile()}'); parts.add('DAY($columnName) ${day.compile()}');
} }
if (hour?.hasValue == true) { if (hour.hasValue == true) {
parts.add('HOUR($columnName) ${hour.compile()}'); parts.add('HOUR($columnName) ${hour.compile()}');
} }
if (minute?.hasValue == true) { if (minute.hasValue == true) {
parts.add('MINUTE($columnName) ${minute.compile()}'); parts.add('MINUTE($columnName) ${minute.compile()}');
} }
if (second?.hasValue == true) { if (second.hasValue == true) {
parts.add('SECOND($columnName) ${second.compile()}'); parts.add('SECOND($columnName) ${second.compile()}');
} }
@ -460,9 +465,9 @@ class DateTimeSqlExpressionBuilder extends SqlExpressionBuilder<DateTime> {
abstract class JsonSqlExpressionBuilder<T, K> extends SqlExpressionBuilder<T> { abstract class JsonSqlExpressionBuilder<T, K> extends SqlExpressionBuilder<T> {
final List<JsonSqlExpressionBuilderProperty> _properties = []; final List<JsonSqlExpressionBuilderProperty> _properties = [];
bool _hasValue = false; bool _hasValue = false;
T _value; T? _value;
String _op; String? _op;
String _raw; String? _raw;
JsonSqlExpressionBuilder(Query query, String columnName) JsonSqlExpressionBuilder(Query query, String columnName)
: super(query, columnName); : super(query, columnName);
@ -480,7 +485,7 @@ abstract class JsonSqlExpressionBuilder<T, K> extends SqlExpressionBuilder<T> {
@override @override
bool get hasValue => _hasValue || _properties.any((p) => p.hasValue); bool get hasValue => _hasValue || _properties.any((p) => p.hasValue);
_encodeValue(T v) => v; T? _encodeValue(T? v) => v;
bool _change(String op, T value) { bool _change(String op, T value) {
_raw = null; _raw = null;
@ -501,7 +506,7 @@ abstract class JsonSqlExpressionBuilder<T, K> extends SqlExpressionBuilder<T> {
} }
@override @override
String compile() { String? compile() {
var s = _compile(); var s = _compile();
if (!_properties.any((p) => p.hasValue)) return s; if (!_properties.any((p) => p.hasValue)) return s;
s ??= ''; s ??= '';
@ -515,7 +520,7 @@ abstract class JsonSqlExpressionBuilder<T, K> extends SqlExpressionBuilder<T> {
s ??= ''; s ??= '';
if (p.typed is! DateTimeSqlExpressionBuilder) { if (p.typed is! DateTimeSqlExpressionBuilder) {
s += '${p.typed.columnName} '; s += '${p.typed!.columnName} ';
} }
s += c; s += c;
@ -526,7 +531,7 @@ abstract class JsonSqlExpressionBuilder<T, K> extends SqlExpressionBuilder<T> {
return s; return s;
} }
String _compile() { String? _compile() {
if (_raw != null) return _raw; if (_raw != null) return _raw;
if (_value == null) return null; if (_value == null) return null;
return "::jsonb $_op @$substitution::jsonb"; return "::jsonb $_op @$substitution::jsonb";
@ -564,7 +569,7 @@ class ListSqlExpressionBuilder extends JsonSqlExpressionBuilder<List, int> {
: super(query, columnName); : super(query, columnName);
@override @override
_encodeValue(List v) => json.encode(v); List<dynamic>? _encodeValue(List<dynamic>? v) => [json.encode(v)];
@override @override
JsonSqlExpressionBuilderProperty _property(int name) { JsonSqlExpressionBuilderProperty _property(int name) {
@ -576,27 +581,27 @@ class JsonSqlExpressionBuilderProperty {
final JsonSqlExpressionBuilder builder; final JsonSqlExpressionBuilder builder;
final String name; final String name;
final bool isInt; final bool isInt;
SqlExpressionBuilder _typed; SqlExpressionBuilder? _typed;
JsonSqlExpressionBuilderProperty(this.builder, this.name, this.isInt); JsonSqlExpressionBuilderProperty(this.builder, this.name, this.isInt);
SqlExpressionBuilder get typed => _typed; SqlExpressionBuilder? get typed => _typed;
bool get hasValue => _typed?.hasValue == true; bool get hasValue => _typed?.hasValue == true;
String compile() => _typed?.compile(); String? compile() => _typed?.compile();
T _set<T extends SqlExpressionBuilder>(T Function() value) { T? _set<T extends SqlExpressionBuilder?>(T Function() value) {
if (_typed is T) { if (_typed is T) {
return _typed as T; return _typed as T?;
} else if (_typed != null) { } else if (_typed != null) {
throw StateError( throw StateError(
'$nameString is already typed as $_typed, and cannot be changed.'); '$nameString is already typed as $_typed, and cannot be changed.');
} else { } else {
_typed = value() _typed = value()
.._cast = 'text' ?.._cast = 'text'
.._isProperty = true; .._isProperty = true;
return _typed as T; return _typed as T?;
} }
} }
@ -608,44 +613,56 @@ class JsonSqlExpressionBuilderProperty {
void get isNotNull { void get isNotNull {
builder builder
.._hasValue = true .._hasValue = true
.._raw ??= '' .._raw ??= '';
.._raw += "$nameString IS NOT NULL";
var r = builder._raw;
if (r != null) {
builder._raw = r + '$nameString IS NOT NULL';
} else {
builder._raw = '$nameString IS NOT NULL';
}
} }
void get isNull { void get isNull {
builder builder
.._hasValue = true .._hasValue = true
.._raw ??= '' .._raw ??= '';
.._raw += "$nameString IS NULL";
var r = builder._raw;
if (r != null) {
builder._raw = r + '$nameString IS NULL';
} else {
builder._raw = '$nameString IS NULL';
}
} }
StringSqlExpressionBuilder get asString { StringSqlExpressionBuilder? get asString {
return _set(() => StringSqlExpressionBuilder(builder.query, nameString)); return _set(() => StringSqlExpressionBuilder(builder.query, nameString));
} }
BooleanSqlExpressionBuilder get asBool { BooleanSqlExpressionBuilder? get asBool {
return _set(() => BooleanSqlExpressionBuilder(builder.query, nameString)); return _set(() => BooleanSqlExpressionBuilder(builder.query, nameString));
} }
DateTimeSqlExpressionBuilder get asDateTime { DateTimeSqlExpressionBuilder? get asDateTime {
return _set(() => DateTimeSqlExpressionBuilder(builder.query, nameString)); return _set(() => DateTimeSqlExpressionBuilder(builder.query, nameString));
} }
NumericSqlExpressionBuilder<double> get asDouble { NumericSqlExpressionBuilder<double>? get asDouble {
return _set( return _set(
() => NumericSqlExpressionBuilder<double>(builder.query, nameString)); () => NumericSqlExpressionBuilder<double>(builder.query, nameString));
} }
NumericSqlExpressionBuilder<int> get asInt { NumericSqlExpressionBuilder<int>? get asInt {
return _set( return _set(
() => NumericSqlExpressionBuilder<int>(builder.query, nameString)); () => NumericSqlExpressionBuilder<int>(builder.query, nameString));
} }
MapSqlExpressionBuilder get asMap { MapSqlExpressionBuilder? get asMap {
return _set(() => MapSqlExpressionBuilder(builder.query, nameString)); return _set(() => MapSqlExpressionBuilder(builder.query, nameString));
} }
ListSqlExpressionBuilder get asList { ListSqlExpressionBuilder? get asList {
return _set(() => ListSqlExpressionBuilder(builder.query, nameString)); return _set(() => ListSqlExpressionBuilder(builder.query, nameString));
} }
} }

View file

@ -5,12 +5,12 @@ import 'query.dart';
class JoinBuilder { class JoinBuilder {
final JoinType type; final JoinType type;
final Query from; final Query from;
final String key, value, op, alias; final String? key, value, op, alias;
final bool aliasAllFields; final bool aliasAllFields;
/// A callback to produces the expression to join against, i.e. /// A callback to produces the expression to join against, i.e.
/// a table name, or the result of compiling a query. /// a table name, or the result of compiling a query.
final String Function() to; final String? Function() to;
final List<String> additionalFields; final List<String> additionalFields;
JoinBuilder(this.type, this.from, this.to, this.key, this.value, JoinBuilder(this.type, this.from, this.to, this.key, this.value,
@ -39,7 +39,7 @@ class JoinBuilder {
return right; return right;
} }
String compile(Set<String> trampoline) { String? compile(Set<String>? trampoline) {
var compiledTo = to(); var compiledTo = to();
if (compiledTo == null) return null; if (compiledTo == null) return null;
var b = StringBuffer(); var b = StringBuffer();

View file

@ -18,16 +18,16 @@ class Column {
final bool isNullable; final bool isNullable;
/// Specifies the length of a `VARCHAR`. /// Specifies the length of a `VARCHAR`.
final int length; final int? length;
/// Explicitly defines a SQL type for this column. /// Explicitly defines a SQL type for this column.
final ColumnType type; final ColumnType? type;
/// Specifies what kind of index this column is, if any. /// Specifies what kind of index this column is, if any.
final IndexType indexType; final IndexType indexType;
/// A custom SQL expression to execute, instead of a named column. /// A custom SQL expression to execute, instead of a named column.
final String expression; final String? expression;
const Column( const Column(
{this.isNullable = true, {this.isNullable = true,
@ -41,7 +41,7 @@ class Column {
} }
class PrimaryKey extends Column { class PrimaryKey extends Column {
const PrimaryKey({ColumnType columnType}) const PrimaryKey({ColumnType? columnType})
: super(type: columnType, indexType: IndexType.primaryKey); : super(type: columnType, indexType: IndexType.primaryKey);
} }

View file

@ -8,21 +8,21 @@ import 'query_values.dart';
import 'query_where.dart'; import 'query_where.dart';
/// A SQL `SELECT` query builder. /// A SQL `SELECT` query builder.
abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> { abstract class Query<T, Where extends QueryWhere?> extends QueryBase<T> {
final List<JoinBuilder> _joins = []; final List<JoinBuilder> _joins = [];
final Map<String, int> _names = {}; final Map<String, int> _names = {};
final List<OrderBy> _orderBy = []; final List<OrderBy> _orderBy = [];
// An optional "parent query". If provided, [reserveName] will operate in // An optional "parent query". If provided, [reserveName] will operate in
// the parent's context. // the parent's context.
final Query parent; final Query? parent;
/// A map of field names to explicit SQL expressions. The expressions will be aliased /// A map of field names to explicit SQL expressions. The expressions will be aliased
/// to the given names. /// to the given names.
final Map<String, String> expressions = {}; final Map<String, String> expressions = {};
String _crossJoin, _groupBy; String? _crossJoin, _groupBy;
int _limit, _offset; int? _limit, _offset;
Query({this.parent}); Query({this.parent});
@ -52,10 +52,19 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
/// Returns a unique version of [name], which will not produce a collision within /// Returns a unique version of [name], which will not produce a collision within
/// the context of this [query]. /// the context of this [query].
String reserveName(String name) { String reserveName(String name) {
if (parent != null) return parent.reserveName(name); if (parent != null) {
var n = _names[name] ??= 0; return parent!.reserveName(name);
_names[name]++; }
return n == 0 ? name : '${name}$n'; // var n = _names[name] ??= 0;
// _names[name]++;
var n = 0;
var nn = _names[name];
if (nn != null) {
n = nn;
nn++;
_names[name] = nn;
}
return n == 0 ? name : '$name$n';
} }
/// Makes a [Where] clause. /// Makes a [Where] clause.
@ -67,27 +76,27 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
/// Determines whether this query can be compiled. /// Determines whether this query can be compiled.
/// ///
/// Used to prevent ambiguities in joins. /// Used to prevent ambiguities in joins.
bool canCompile(Set<String> trampoline) => true; bool canCompile(Set<String>? trampoline) => true;
/// Shorthand for calling [where].or with a [Where] clause. /// Shorthand for calling [where].or with a [Where] clause.
void andWhere(void Function(Where) f) { void andWhere(void Function(Where) f) {
var w = newWhereClause(); var w = newWhereClause();
f(w); f(w);
where.and(w); where?.and(w);
} }
/// Shorthand for calling [where].or with a [Where] clause. /// Shorthand for calling [where].or with a [Where] clause.
void notWhere(void Function(Where) f) { void notWhere(void Function(Where) f) {
var w = newWhereClause(); var w = newWhereClause();
f(w); f(w);
where.not(w); where?.not(w);
} }
/// Shorthand for calling [where].or with a [Where] clause. /// Shorthand for calling [where].or with a [Where] clause.
void orWhere(void Function(Where) f) { void orWhere(void Function(Where) f) {
var w = newWhereClause(); var w = newWhereClause();
f(w); f(w);
where.or(w); where?.or(w);
} }
/// Limit the number of rows to return. /// Limit the number of rows to return.
@ -115,12 +124,12 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
_crossJoin = tableName; _crossJoin = tableName;
} }
String _joinAlias(Set<String> trampoline) { String _joinAlias(Set<String>? trampoline) {
int i = _joins.length; int i = _joins.length;
while (true) { while (true) {
var a = 'a$i'; var a = 'a$i';
if (trampoline.add(a)) { if (trampoline!.add(a)) {
return a; return a;
} else { } else {
i++; i++;
@ -128,7 +137,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
} }
} }
String Function() _compileJoin(tableName, Set<String> trampoline) { String? Function() _compileJoin(tableName, Set<String>? trampoline) {
if (tableName is String) { if (tableName is String) {
return () => tableName; return () => tableName;
} else if (tableName is Query) { } else if (tableName is Query) {
@ -145,7 +154,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
void _makeJoin( void _makeJoin(
tableName, tableName,
Set<String> trampoline, Set<String>? trampoline,
JoinType type, JoinType type,
String localKey, String localKey,
String foreignKey, String foreignKey,
@ -180,7 +189,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
void join(tableName, String localKey, String foreignKey, void join(tableName, String localKey, String foreignKey,
{String op = '=', {String op = '=',
List<String> additionalFields = const [], List<String> additionalFields = const [],
Set<String> trampoline}) { Set<String>? trampoline}) {
_makeJoin(tableName, trampoline, JoinType.inner, localKey, foreignKey, op, _makeJoin(tableName, trampoline, JoinType.inner, localKey, foreignKey, op,
additionalFields); additionalFields);
} }
@ -189,7 +198,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
void leftJoin(tableName, String localKey, String foreignKey, void leftJoin(tableName, String localKey, String foreignKey,
{String op = '=', {String op = '=',
List<String> additionalFields = const [], List<String> additionalFields = const [],
Set<String> trampoline}) { Set<String>? trampoline}) {
_makeJoin(tableName, trampoline, JoinType.left, localKey, foreignKey, op, _makeJoin(tableName, trampoline, JoinType.left, localKey, foreignKey, op,
additionalFields); additionalFields);
} }
@ -198,7 +207,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
void rightJoin(tableName, String localKey, String foreignKey, void rightJoin(tableName, String localKey, String foreignKey,
{String op = '=', {String op = '=',
List<String> additionalFields = const [], List<String> additionalFields = const [],
Set<String> trampoline}) { Set<String>? trampoline}) {
_makeJoin(tableName, trampoline, JoinType.right, localKey, foreignKey, op, _makeJoin(tableName, trampoline, JoinType.right, localKey, foreignKey, op,
additionalFields); additionalFields);
} }
@ -207,7 +216,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
void fullOuterJoin(tableName, String localKey, String foreignKey, void fullOuterJoin(tableName, String localKey, String foreignKey,
{String op = '=', {String op = '=',
List<String> additionalFields = const [], List<String> additionalFields = const [],
Set<String> trampoline}) { Set<String>? trampoline}) {
_makeJoin(tableName, trampoline, JoinType.full, localKey, foreignKey, op, _makeJoin(tableName, trampoline, JoinType.full, localKey, foreignKey, op,
additionalFields); additionalFields);
} }
@ -216,17 +225,17 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
void selfJoin(tableName, String localKey, String foreignKey, void selfJoin(tableName, String localKey, String foreignKey,
{String op = '=', {String op = '=',
List<String> additionalFields = const [], List<String> additionalFields = const [],
Set<String> trampoline}) { Set<String>? trampoline}) {
_makeJoin(tableName, trampoline, JoinType.self, localKey, foreignKey, op, _makeJoin(tableName, trampoline, JoinType.self, localKey, foreignKey, op,
additionalFields); additionalFields);
} }
@override @override
String compile(Set<String> trampoline, String? compile(Set<String>? trampoline,
{bool includeTableName = false, {bool includeTableName = false,
String preamble, String? preamble,
bool withFields = true, bool withFields = true,
String fromQuery}) { String? fromQuery}) {
// One table MAY appear multiple times in a query. // One table MAY appear multiple times in a query.
if (!canCompile(trampoline)) { if (!canCompile(trampoline)) {
return null; return null;
@ -237,13 +246,13 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
b.write(' '); b.write(' ');
List<String> f; List<String> f;
var compiledJoins = <JoinBuilder, String>{}; var compiledJoins = <JoinBuilder, String?>{};
if (fields == null) { if (fields == null) {
f = ['*']; f = ['*'];
} else { } else {
f = List<String>.from(fields.map((s) { f = List<String>.from(fields.map((s) {
var ss = includeTableName ? '$tableName.$s' : s; String? ss = includeTableName ? '$tableName.$s' : s;
if (expressions.containsKey(s)) { if (expressions.containsKey(s)) {
// ss = '(' + expressions[s] + ')'; // ss = '(' + expressions[s] + ')';
ss = expressions[s]; ss = expressions[s];
@ -297,8 +306,10 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
} }
var whereClause = var whereClause =
where.compile(tableName: includeTableName ? tableName : null); where?.compile(tableName: includeTableName ? tableName : null);
if (whereClause.isNotEmpty) b.write(' WHERE $whereClause'); if (whereClause?.isNotEmpty == true) {
b.write(' WHERE $whereClause');
}
if (_groupBy != null) b.write(' GROUP BY $_groupBy'); if (_groupBy != null) b.write(' GROUP BY $_groupBy');
for (var item in _orderBy) { for (var item in _orderBy) {
b.write(' ORDER BY ${item.compile()}'); b.write(' ORDER BY ${item.compile()}');
@ -309,13 +320,13 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
} }
@override @override
Future<T> getOne(QueryExecutor executor) { Future<T?> getOne(QueryExecutor executor) {
//limit(1); //limit(1);
return super.getOne(executor); return super.getOne(executor);
} }
Future<List<T>> delete(QueryExecutor executor) { Future<List<T>> delete(QueryExecutor executor) {
var sql = compile(Set(), preamble: 'DELETE', withFields: false); var sql = compile({}, preamble: 'DELETE', withFields: false);
if (_joins.isEmpty) { if (_joins.isEmpty) {
return executor return executor
@ -334,11 +345,11 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
} }
} }
Future<T> deleteOne(QueryExecutor executor) { Future<T?> deleteOne(QueryExecutor executor) {
return delete(executor).then((it) => it.isEmpty ? null : it.first); return delete(executor).then((it) => it.isEmpty ? null : it.first);
} }
Future<T> insert(QueryExecutor executor) { Future<T?> insert(QueryExecutor executor) {
var insertion = values.compileInsert(this, tableName); var insertion = values.compileInsert(this, tableName);
if (insertion == null) { if (insertion == null) {
@ -346,7 +357,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
} else { } else {
// TODO: How to do this in a non-Postgres DB? // TODO: How to do this in a non-Postgres DB?
var returning = fields.map(adornWithTableName).join(', '); var returning = fields.map(adornWithTableName).join(', ');
var sql = compile(Set()); var sql = compile({})!;
sql = 'WITH $tableName as ($insertion RETURNING $returning) ' + sql; sql = 'WITH $tableName as ($insertion RETURNING $returning) ' + sql;
return executor return executor
.query(tableName, sql, substitutionValues) .query(tableName, sql, substitutionValues)
@ -362,12 +373,14 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
throw StateError('No values have been specified for update.'); throw StateError('No values have been specified for update.');
} else { } else {
updateSql.write(' $valuesClause'); updateSql.write(' $valuesClause');
var whereClause = where.compile(); var whereClause = where?.compile();
if (whereClause.isNotEmpty) updateSql.write(' WHERE $whereClause'); if (whereClause?.isNotEmpty == true) {
updateSql.write(' WHERE $whereClause');
}
if (_limit != null) updateSql.write(' LIMIT $_limit'); if (_limit != null) updateSql.write(' LIMIT $_limit');
var returning = fields.map(adornWithTableName).join(', '); var returning = fields.map(adornWithTableName).join(', ');
var sql = compile(Set()); var sql = compile({})!;
sql = 'WITH $tableName as ($updateSql RETURNING $returning) ' + sql; sql = 'WITH $tableName as ($updateSql RETURNING $returning) ' + sql;
return executor return executor
@ -376,7 +389,7 @@ abstract class Query<T, Where extends QueryWhere> extends QueryBase<T> {
} }
} }
Future<T> updateOne(QueryExecutor executor) { Future<T?> updateOne(QueryExecutor executor) {
return update(executor).then((it) => it.isEmpty ? null : it.first); return update(executor).then((it) => it.isEmpty ? null : it.first);
} }
} }

View file

@ -32,19 +32,21 @@ abstract class QueryBase<T> {
} }
}).join(', '); }).join(', ');
String compile(Set<String> trampoline, String? compile(Set<String> trampoline,
{bool includeTableName = false, String preamble, bool withFields = true}); {bool includeTableName = false,
String? preamble,
bool withFields = true});
T deserialize(List row); T deserialize(List row);
Future<List<T>> get(QueryExecutor executor) async { Future<List<T>> get(QueryExecutor executor) async {
var sql = compile(Set()); var sql = compile({});
return executor return executor
.query(tableName, sql, substitutionValues) .query(tableName, sql, substitutionValues)
.then((it) => it.map(deserialize).toList()); .then((it) => it.map(deserialize).toList());
} }
Future<T> getOne(QueryExecutor executor) { Future<T?> getOne(QueryExecutor executor) {
return get(executor).then((it) => it.isEmpty ? null : it.first); return get(executor).then((it) => it.isEmpty ? null : it.first);
} }

View file

@ -8,8 +8,8 @@ abstract class QueryExecutor {
/// Executes a single query. /// Executes a single query.
Future<List<List>> query( Future<List<List>> query(
String tableName, String query, Map<String, dynamic> substitutionValues, String tableName, String? query, Map<String, dynamic> substitutionValues,
[List<String> returningFields]); [List<String>? returningFields]);
/// Enters a database transaction, performing the actions within, /// Enters a database transaction, performing the actions within,
/// and returning the results of [f]. /// and returning the results of [f].

View file

@ -14,7 +14,7 @@ abstract class QueryValues {
} }
} }
String compileInsert(Query query, String tableName) { String? compileInsert(Query query, String tableName) {
var data = Map<String, dynamic>.from(toMap()); var data = Map<String, dynamic>.from(toMap());
var keys = data.keys.toList(); var keys = data.keys.toList();
keys.where((k) => !query.fields.contains(k)).forEach(data.remove); keys.where((k) => !query.fields.contains(k)).forEach(data.remove);
@ -37,7 +37,7 @@ abstract class QueryValues {
return b.toString(); return b.toString();
} }
String compileForUpdate(Query query) { String? compileForUpdate(Query query) {
var data = toMap(); var data = toMap();
if (data.isEmpty) return null; if (data.isEmpty) return null;
var b = StringBuffer('SET'); var b = StringBuffer('SET');

View file

@ -2,25 +2,25 @@ import 'builder.dart';
/// Builds a SQL `WHERE` clause. /// Builds a SQL `WHERE` clause.
abstract class QueryWhere { abstract class QueryWhere {
final Set<QueryWhere> _and = Set(); final Set<QueryWhere?> _and = Set();
final Set<QueryWhere> _not = Set(); final Set<QueryWhere?> _not = Set();
final Set<QueryWhere> _or = Set(); final Set<QueryWhere?> _or = Set();
Iterable<SqlExpressionBuilder> get expressionBuilders; Iterable<SqlExpressionBuilder> get expressionBuilders;
void and(QueryWhere other) { void and(QueryWhere? other) {
_and.add(other); _and.add(other);
} }
void not(QueryWhere other) { void not(QueryWhere? other) {
_not.add(other); _not.add(other);
} }
void or(QueryWhere other) { void or(QueryWhere? other) {
_or.add(other); _or.add(other);
} }
String compile({String tableName}) { String compile({String? tableName}) {
var b = StringBuffer(); var b = StringBuffer();
int i = 0; int i = 0;
@ -40,17 +40,17 @@ abstract class QueryWhere {
} }
for (var other in _and) { for (var other in _and) {
var sql = other.compile(); var sql = other!.compile();
if (sql.isNotEmpty) b.write(' AND ($sql)'); if (sql.isNotEmpty) b.write(' AND ($sql)');
} }
for (var other in _not) { for (var other in _not) {
var sql = other.compile(); var sql = other!.compile();
if (sql.isNotEmpty) b.write(' NOT ($sql)'); if (sql.isNotEmpty) b.write(' NOT ($sql)');
} }
for (var other in _or) { for (var other in _or) {
var sql = other.compile(); var sql = other!.compile();
if (sql.isNotEmpty) b.write(' OR ($sql)'); if (sql.isNotEmpty) b.write(' OR ($sql)');
} }

View file

@ -9,11 +9,11 @@ abstract class RelationshipType {
class Relationship { class Relationship {
final int type; final int type;
final String localKey; final String? localKey;
final String foreignKey; final String? foreignKey;
final String foreignTable; final String? foreignTable;
final bool cascadeOnDelete; final bool? cascadeOnDelete;
final JoinType joinType; final JoinType? joinType;
const Relationship(this.type, const Relationship(this.type,
{this.localKey, {this.localKey,
@ -25,11 +25,11 @@ class Relationship {
class HasMany extends Relationship { class HasMany extends Relationship {
const HasMany( const HasMany(
{String localKey, {String? localKey,
String foreignKey, String? foreignKey,
String foreignTable, String? foreignTable,
bool cascadeOnDelete = false, bool cascadeOnDelete = false,
JoinType joinType}) JoinType? joinType})
: super(RelationshipType.hasMany, : super(RelationshipType.hasMany,
localKey: localKey, localKey: localKey,
foreignKey: foreignKey, foreignKey: foreignKey,
@ -42,11 +42,11 @@ const HasMany hasMany = HasMany();
class HasOne extends Relationship { class HasOne extends Relationship {
const HasOne( const HasOne(
{String localKey, {String? localKey,
String foreignKey, String? foreignKey,
String foreignTable, String? foreignTable,
bool cascadeOnDelete = false, bool cascadeOnDelete = false,
JoinType joinType}) JoinType? joinType})
: super(RelationshipType.hasOne, : super(RelationshipType.hasOne,
localKey: localKey, localKey: localKey,
foreignKey: foreignKey, foreignKey: foreignKey,
@ -59,10 +59,10 @@ const HasOne hasOne = HasOne();
class BelongsTo extends Relationship { class BelongsTo extends Relationship {
const BelongsTo( const BelongsTo(
{String localKey, {String? localKey,
String foreignKey, String? foreignKey,
String foreignTable, String? foreignTable,
JoinType joinType}) JoinType? joinType})
: super(RelationshipType.belongsTo, : super(RelationshipType.belongsTo,
localKey: localKey, localKey: localKey,
foreignKey: foreignKey, foreignKey: foreignKey,
@ -76,11 +76,11 @@ class ManyToMany extends Relationship {
final Type through; final Type through;
const ManyToMany(this.through, const ManyToMany(this.through,
{String localKey, {String? localKey,
String foreignKey, String? foreignKey,
String foreignTable, String? foreignTable,
bool cascadeOnDelete = false, bool cascadeOnDelete = false,
JoinType joinType}) JoinType? joinType})
: super( : super(
RelationshipType.hasMany, // Many-to-Many is actually just a hasMany RelationshipType.hasMany, // Many-to-Many is actually just a hasMany
localKey: localKey, localKey: localKey,

View file

@ -11,7 +11,7 @@ class Union<T> extends QueryBase<T> {
@override @override
final String tableName; final String tableName;
Union(this.left, this.right, {this.all = false, String tableName}) Union(this.left, this.right, {this.all = false, String? tableName})
: this.tableName = tableName ?? left.tableName { : this.tableName = tableName ?? left.tableName {
substitutionValues substitutionValues
..addAll(left.substitutionValues) ..addAll(left.substitutionValues)
@ -27,7 +27,7 @@ class Union<T> extends QueryBase<T> {
@override @override
String compile(Set<String> trampoline, String compile(Set<String> trampoline,
{bool includeTableName = false, {bool includeTableName = false,
String preamble, String? preamble,
bool withFields = true}) { bool withFields = true}) {
var selector = all == true ? 'UNION ALL' : 'UNION'; var selector = all == true ? 'UNION ALL' : 'UNION';
var t1 = Set<String>.from(trampoline); var t1 = Set<String>.from(trampoline);

View file

@ -1,10 +1,9 @@
name: angel_orm name: angel_orm
version: 3.0.0 version: 4.0.0
description: Runtime support for Angel's ORM. Includes base classes for queries. description: Runtime support for Angel's ORM. Includes base classes for queries.
author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/orm homepage: https://github.com/angel-dart/orm
environment: environment:
sdk: '>=2.10.0 <3.0.0' sdk: '>=2.12.0 <3.0.0'
dependencies: dependencies:
charcode: ^1.2.0 charcode: ^1.2.0
intl: ^0.17.0 intl: ^0.17.0
@ -14,18 +13,18 @@ dev_dependencies:
angel_model: angel_model:
git: git:
url: https://github.com/dukefirehawk/angel.git url: https://github.com/dukefirehawk/angel.git
ref: sdk-2.12.x ref: sdk-2.12.x_nnbd
path: packages/model path: packages/model
angel_serialize: angel_serialize:
git: git:
url: https://github.com/dukefirehawk/angel.git url: https://github.com/dukefirehawk/angel.git
ref: sdk-2.12.x ref: sdk-2.12.x_nnbd
path: packages/serialize/angel_serialize path: packages/serialize/angel_serialize
angel_serialize_generator: angel_serialize_generator:
git: git:
url: https://github.com/dukefirehawk/angel.git url: https://github.com/dukefirehawk/angel.git
ref: sdk-2.12.x ref: sdk-2.12.x_nnbd
path: packages/serialize/angel_serialize_generator path: packages/serialize/angel_serialize_generator
build_runner: ^1.11.5 build_runner: ^2.0.1
pedantic: ^1.11.0 pedantic: ^1.11.0
test: ^1.16.5 test: ^1.17.3

View file

@ -0,0 +1,2 @@
Tobe O <thosakwe@gmail.com>
Thomas Hii <thomashii@dukefirehawk.com>

View file

@ -1,3 +1,9 @@
# 4.0.0
* Migrated to support Dart SDK 2.12.x NNBD
# 3.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
# 2.1.0-beta.2 # 2.1.0-beta.2
* Support for custom SQL expressions. * Support for custom SQL expressions.

View file

@ -0,0 +1,2 @@
Tobe O <thosakwe@gmail.com>
Thomas Hii <thomashii@dukefirehawk.com>

View file

@ -0,0 +1,8 @@
# 3.0.0
* Migrated to support Dart SDK 2.12.x NNBD
# 2.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
# 1.0.0
* First version.

View file

@ -0,0 +1,2 @@
Tobe O <thosakwe@gmail.com>
Thomas Hii <thomashii@dukefirehawk.com>

View file

@ -1,3 +1,9 @@
# 3.0.0
* Migrated to support Dart SDK 2.12.x NNBD
# 2.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
# 1.1.0-beta.1 # 1.1.0-beta.1
* Improvements in how transactions are handled; rethrow failed exceptions after rolling back. * Improvements in how transactions are handled; rethrow failed exceptions after rolling back.
* Remove deprecated executor classes. * Remove deprecated executor classes.

View file

@ -0,0 +1,2 @@
Tobe O <thosakwe@gmail.com>
Thomas Hii <thomashii@dukefirehawk.com>

View file

@ -0,0 +1,8 @@
# 3.0.0
* Migrated to support Dart SDK 2.12.x NNBD
# 2.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
# 1.0.0
* First version.