mirror of https://github.com/AMT-Cheif/drift.git
Init repository
This commit is contained in:
parent
5a450c8e76
commit
5abefa7494
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
|
||||||
|
</project>
|
|
@ -0,0 +1,626 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Dart Packages" type="DartPackagesLibraryType">
|
||||||
|
<properties>
|
||||||
|
<option name="packageNameToDirsMap">
|
||||||
|
<entry key="analyzer">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/analyzer-0.34.3/lib" />
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/analyzer-0.35.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="analyzer_plugin">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.0.1-alpha.6/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="args">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/args-1.5.1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="async">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/async-2.0.8/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="boolean_selector">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.4/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="build">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build-1.1.0/lib" />
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build-1.1.1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="build_config">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_config-0.3.1+4/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="build_daemon">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_daemon-0.2.3/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="build_resolvers">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_resolvers-0.2.3/lib" />
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_resolvers-1.0.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="build_runner">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_runner-1.2.3/lib" />
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_runner-1.2.5/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="build_runner_core">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_runner_core-2.0.1/lib" />
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_runner_core-2.0.2/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="build_test">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_test-0.10.6/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="built_collection">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/built_collection-4.1.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="built_value">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/built_value-6.3.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="built_value_generator">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/built_value_generator-6.3.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="charcode">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.2/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="code_builder">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/code_builder-3.2.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="collection">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/collection-1.14.11/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="convert">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/convert-2.1.1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="crypto">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/crypto-2.0.6/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="csslib">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/csslib-0.14.6/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="dart_style">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/dart_style-1.2.3/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="fixnum">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/fixnum-0.10.9/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="front_end">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/front_end-0.1.9+1/lib" />
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/front_end-0.1.10/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="glob">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/glob-1.1.7/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="graphs">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/graphs-0.2.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="html">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/html-0.13.3+3/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="http">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http-0.12.0+1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="http_multi_server">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http_multi_server-2.0.5/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="http_parser">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http_parser-3.1.3/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="io">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/io-0.3.3/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="js">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/js-0.6.1+1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="json_annotation">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/json_annotation-2.0.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="json_rpc_2">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/json_rpc_2-2.0.9/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="kernel">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/kernel-0.3.9+1/lib" />
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/kernel-0.3.10/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="logging">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/logging-0.11.3+2/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="matcher">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.3+1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="meta">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/meta-1.1.7/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="mime">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/mime-0.9.6+2/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="mockito">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/mockito-4.0.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="multi_server_socket">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/multi_server_socket-1.0.2/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="node_preamble">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/node_preamble-1.4.4/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="package_config">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_config-1.0.5/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="package_resolver">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_resolver-1.0.6/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="path">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path-1.6.2/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="pedantic">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pedantic-1.4.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="plugin">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/plugin-0.2.0+3/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="pool">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pool-1.4.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="pub_semver">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pub_semver-1.4.2/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="pubspec_parse">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-0.1.4/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="quiver">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/quiver-2.0.1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="recase">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/recase-2.0.1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="shelf">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf-0.7.4/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="shelf_packages_handler">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-1.0.4/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="shelf_static">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_static-0.2.8/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="shelf_web_socket">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-0.2.2+4/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="source_gen">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_gen-0.9.4+1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="source_map_stack_trace">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-1.1.5/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="source_maps">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.8/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="source_span">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.4/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="stack_trace">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="stream_channel">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stream_channel-1.6.8/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="stream_transform">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stream_transform-0.0.14+1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="string_scanner">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.4/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="term_glyph">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.1.0/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="test">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/test-1.5.3/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="test_api">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/test_api-0.2.2/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="test_core">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/test_core-0.2.1+1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="timing">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/timing-0.1.1+1/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="typed_data">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/typed_data-1.1.6/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="utf">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/utf-0.9.0+5/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="vm_service_client">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/vm_service_client-0.2.6/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="watcher">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/watcher-0.9.7+10/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="web_socket_channel">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-1.0.9/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="yaml">
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<option value="$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/yaml-2.1.15/lib" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</option>
|
||||||
|
</properties>
|
||||||
|
<CLASSES>
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/analyzer-0.34.3/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/analyzer-0.35.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/analyzer_plugin-0.0.1-alpha.6/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/args-1.5.1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/async-2.0.8/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.4/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build-1.1.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build-1.1.1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_config-0.3.1+4/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_daemon-0.2.3/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_resolvers-0.2.3/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_resolvers-1.0.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_runner-1.2.3/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_runner-1.2.5/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_runner_core-2.0.1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_runner_core-2.0.2/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/build_test-0.10.6/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/built_collection-4.1.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/built_value-6.3.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/built_value_generator-6.3.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.2/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/code_builder-3.2.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/collection-1.14.11/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/convert-2.1.1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/crypto-2.0.6/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/csslib-0.14.6/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/dart_style-1.2.3/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/fixnum-0.10.9/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/front_end-0.1.10/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/front_end-0.1.9+1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/glob-1.1.7/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/graphs-0.2.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/html-0.13.3+3/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http-0.12.0+1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http_multi_server-2.0.5/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/http_parser-3.1.3/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/io-0.3.3/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/js-0.6.1+1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/json_annotation-2.0.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/json_rpc_2-2.0.9/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/kernel-0.3.10/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/kernel-0.3.9+1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/logging-0.11.3+2/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.3+1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/meta-1.1.7/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/mime-0.9.6+2/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/mockito-4.0.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/multi_server_socket-1.0.2/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/node_preamble-1.4.4/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_config-1.0.5/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_resolver-1.0.6/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/path-1.6.2/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pedantic-1.4.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/plugin-0.2.0+3/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pool-1.4.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pub_semver-1.4.2/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-0.1.4/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/quiver-2.0.1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/recase-2.0.1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf-0.7.4/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_packages_handler-1.0.4/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_static-0.2.8/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/shelf_web_socket-0.2.2+4/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_gen-0.9.4+1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_map_stack_trace-1.1.5/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_maps-0.10.8/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.4/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stream_channel-1.6.8/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/stream_transform-0.0.14+1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.4/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.1.0/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/test-1.5.3/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/test_api-0.2.2/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/test_core-0.2.1+1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/timing-0.1.1+1/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/typed_data-1.1.6/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/utf-0.9.0+5/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/vm_service_client-0.2.6/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/watcher-0.9.7+10/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/web_socket_channel-1.0.9/lib" />
|
||||||
|
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/yaml-2.1.15/lib" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Dart SDK">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="file:///opt/dart-sdk/lib/async" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/cli" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/collection" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/convert" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/core" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/developer" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/html" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/indexed_db" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/io" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/isolate" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/js" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/js_util" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/math" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/mirrors" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/svg" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/typed_data" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/web_audio" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/web_gl" />
|
||||||
|
<root url="file:///opt/dart-sdk/lib/web_sql" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/example/example.iml" filepath="$PROJECT_DIR$/example/example.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/sally/sally.iml" filepath="$PROJECT_DIR$/sally/sally.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/sally_generator/sally_generator.iml" filepath="$PROJECT_DIR$/sally_generator/sally_generator.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,48 @@
|
||||||
|
# Created with package:mono_repo v1.2.1
|
||||||
|
language: dart
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
include:
|
||||||
|
- stage: analyze
|
||||||
|
name: "SDK: stable - DIR: sally - TASKS: dartanalyzer ."
|
||||||
|
script: ./tool/travis.sh dartanalyzer
|
||||||
|
env: PKG="sally"
|
||||||
|
dart: stable
|
||||||
|
- stage: analyze
|
||||||
|
name: "SDK: stable - DIR: sally - TASKS: dartfmt -n --set-exit-if-changed ."
|
||||||
|
script: ./tool/travis.sh dartfmt
|
||||||
|
env: PKG="sally"
|
||||||
|
dart: stable
|
||||||
|
- stage: unit_test
|
||||||
|
name: "SDK: stable - DIR: sally - TASKS: pub run test"
|
||||||
|
script: ./tool/travis.sh test
|
||||||
|
env: PKG="sally"
|
||||||
|
dart: stable
|
||||||
|
- stage: analyze
|
||||||
|
name: "SDK: stable - DIR: sally_generator - TASKS: dartanalyzer ."
|
||||||
|
script: ./tool/travis.sh dartanalyzer
|
||||||
|
env: PKG="sally_generator"
|
||||||
|
dart: stable
|
||||||
|
- stage: analyze
|
||||||
|
name: "SDK: stable - DIR: sally_generator - TASKS: dartfmt -n --set-exit-if-changed ."
|
||||||
|
script: ./tool/travis.sh dartfmt
|
||||||
|
env: PKG="sally_generator"
|
||||||
|
dart: stable
|
||||||
|
- stage: unit_test
|
||||||
|
name: "SDK: stable - DIR: sally_generator - TASKS: pub run test"
|
||||||
|
script: ./tool/travis.sh test
|
||||||
|
env: PKG="sally_generator"
|
||||||
|
dart: stable
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- analyze
|
||||||
|
- unit_test
|
||||||
|
|
||||||
|
# Only building master means that we don't run two builds for each pull request.
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- "$HOME/.pub-cache"
|
|
@ -0,0 +1,3 @@
|
||||||
|
## 1.0.0
|
||||||
|
|
||||||
|
- Initial version, created by Stagehand
|
|
@ -0,0 +1,4 @@
|
||||||
|
A sample command-line application.
|
||||||
|
|
||||||
|
Created from templates made available by Stagehand under a BSD-style
|
||||||
|
[license](https://github.com/dart-lang/stagehand/blob/master/LICENSE).
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||||
|
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
|
@ -0,0 +1,26 @@
|
||||||
|
import 'package:sally/sally.dart';
|
||||||
|
import 'package:sally/src/queries/table_structure.dart';
|
||||||
|
|
||||||
|
part 'example.g.dart';
|
||||||
|
|
||||||
|
class Products extends Table {
|
||||||
|
|
||||||
|
IntColumn get id => integer().named("products_id").autoIncrement()();
|
||||||
|
TextColumn get name => text()();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Users extends Table {
|
||||||
|
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
TextColumn get name => text().withLength(min: 6, max: 32)();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseData(tables: [Products, Users])
|
||||||
|
class ShopDb extends SallyDb with _$ShopDbMixin {
|
||||||
|
|
||||||
|
Future<List<User>> allUsers() => users.select().get();
|
||||||
|
Future<User> userByName(String name) => users.select().where((u) => u.name.equals(name)).single();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
part of 'example.dart';
|
||||||
|
|
||||||
|
class _$ShopDbMixin implements QueryExecutor {
|
||||||
|
|
||||||
|
final StructuredUsersTable users = StructuredUsersTable();
|
||||||
|
|
||||||
|
Future<List<Map<String, dynamic>>> executeQuery(String sql, [dynamic params]) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class StructuredUsersTable extends Users with TableStructure<Users, User> {
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
final StructuredIntColumn id = StructuredIntColumn("id");
|
||||||
|
@override
|
||||||
|
final StructuredTextColumn name = StructuredTextColumn("name");
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sqlTableName => "users";
|
||||||
|
|
||||||
|
@override
|
||||||
|
User parse(Map<String, dynamic> result) {
|
||||||
|
return User(result["id"], result["name"]);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Users get asTable => this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class User {
|
||||||
|
|
||||||
|
final int id;
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
User(this.id, this.name);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
name: example
|
||||||
|
description: A sample command-line application.
|
||||||
|
# version: 1.0.0
|
||||||
|
# homepage: https://www.example.com
|
||||||
|
# author: simon <email@example.com>
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.1.0 <3.0.0'
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
sally:
|
||||||
|
path: ../sally
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
sally_generator:
|
||||||
|
path: ../sally_generator
|
||||||
|
build_runner:
|
||||||
|
pedantic: ^1.0.0
|
||||||
|
test: ^1.0.0
|
|
@ -26,82 +26,5 @@ doc/api/
|
||||||
*.js.map
|
*.js.map
|
||||||
|
|
||||||
### Intellij ###
|
### Intellij ###
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
.idea/**/*
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
||||||
|
|
||||||
# User-specific stuff
|
|
||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/**/usage.statistics.xml
|
|
||||||
.idea/**/dictionaries
|
|
||||||
.idea/**/shelf
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
.idea/**/contentModel.xml
|
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
.idea/**/dbnavigator.xml
|
|
||||||
|
|
||||||
# Gradle
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
|
|
||||||
# Gradle and Maven with auto-import
|
|
||||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
||||||
# since they will be recreated, and may cause churn. Uncomment if using
|
|
||||||
# auto-import.
|
|
||||||
# .idea/modules.xml
|
|
||||||
# .idea/*.iml
|
|
||||||
# .idea/modules
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
cmake-build-*/
|
|
||||||
|
|
||||||
# Mongo Explorer plugin
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
|
|
||||||
# File-based project format
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
out/
|
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Cursive Clojure plugin
|
|
||||||
.idea/replstate.xml
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
|
|
||||||
# Editor-based Rest Client
|
|
||||||
.idea/httpRequests
|
|
||||||
|
|
||||||
# Android studio 3.1+ serialized cache file
|
|
||||||
.idea/caches/build_file_checksums.ser
|
|
||||||
|
|
||||||
### Intellij Patch ###
|
|
||||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
|
||||||
|
|
||||||
# *.iml
|
|
||||||
# modules.xml
|
|
||||||
# .idea/misc.xml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# Sonarlint plugin
|
|
||||||
.idea/sonarlint
|
|
||||||
|
|
||||||
# End of https://www.gitignore.io/api/dart,intellij
|
# End of https://www.gitignore.io/api/dart,intellij
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
## 1.0.0
|
||||||
|
|
||||||
|
- Initial version, created by Stagehand
|
|
@ -0,0 +1,22 @@
|
||||||
|
A library for Dart developers.
|
||||||
|
|
||||||
|
Created from templates made available by Stagehand under a BSD-style
|
||||||
|
[license](https://github.com/dart-lang/stagehand/blob/master/LICENSE).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
A simple usage example:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
import 'package:sally/sally.dart';
|
||||||
|
|
||||||
|
main() {
|
||||||
|
var awesome = new Awesome();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features and bugs
|
||||||
|
|
||||||
|
Please file feature requests and bugs at the [issue tracker][tracker].
|
||||||
|
|
||||||
|
[tracker]: http://example.com/issues/replaceme
|
|
@ -0,0 +1,5 @@
|
||||||
|
library sally;
|
||||||
|
|
||||||
|
export 'package:sally/src/dsl/table.dart';
|
||||||
|
export 'package:sally/src/dsl/columns.dart';
|
||||||
|
export 'package:sally/src/database.dart';
|
|
@ -0,0 +1,12 @@
|
||||||
|
class UseData {
|
||||||
|
final List<Type> tables;
|
||||||
|
final int schemaVersion;
|
||||||
|
|
||||||
|
const UseData({this.tables, this.schemaVersion = 1});
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class QueryExecutor {
|
||||||
|
Future<List<Map<String, dynamic>>> executeQuery(String sql, [dynamic params]);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class SallyDb {}
|
|
@ -0,0 +1,70 @@
|
||||||
|
// todo more datatypes (at least DateTime and Binary blobs)!
|
||||||
|
// todo nullability
|
||||||
|
|
||||||
|
import 'package:sally/src/queries/predicates/predicate.dart';
|
||||||
|
|
||||||
|
class Column<T> {
|
||||||
|
Predicate equals(T compare) => null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class IntColumn extends Column<int> {
|
||||||
|
Predicate isBiggerThan(int i) => null;
|
||||||
|
Predicate isSmallerThan(int i) => null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BoolColumn extends Column<bool> {
|
||||||
|
Predicate isTrue() => null;
|
||||||
|
Predicate isFalse() => null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TextColumn extends Column<String> {
|
||||||
|
Predicate like(String regex) => null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColumnBuilder<T> {
|
||||||
|
/// By default, the field name will be used as the column name, e.g.
|
||||||
|
/// `IntColumn get id = integer()` will have "id" as its associated name. To change
|
||||||
|
/// this, use `IntColumn get id = integer((c) => c.named('user_id'))`.
|
||||||
|
ColumnBuilder<T> named(String name) => this;
|
||||||
|
ColumnBuilder<T> primaryKey() => this;
|
||||||
|
// ColumnBuilder<T> references<Table>(Column<T> extractor(Table table)) => this;
|
||||||
|
|
||||||
|
Column<T> call() => null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class IntColumnBuilder extends ColumnBuilder<int> {
|
||||||
|
@override
|
||||||
|
IntColumnBuilder named(String name) => this;
|
||||||
|
@override
|
||||||
|
IntColumnBuilder primaryKey() => this;
|
||||||
|
// @override
|
||||||
|
// IntColumnBuilder references<Table>(Column<int> extractor(Table table)) => this;
|
||||||
|
@override
|
||||||
|
IntColumn call() => null;
|
||||||
|
|
||||||
|
IntColumnBuilder autoIncrement() => this;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BoolColumnBuilder extends ColumnBuilder<bool> {
|
||||||
|
@override
|
||||||
|
BoolColumnBuilder named(String name) => this;
|
||||||
|
@override
|
||||||
|
BoolColumnBuilder primaryKey() => this;
|
||||||
|
// @override
|
||||||
|
// BoolColumnBuilder references<Table>(Column<bool> extractor(Table table)) => this;
|
||||||
|
@override
|
||||||
|
BoolColumn call() => null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TextColumnBuilder extends ColumnBuilder<String> {
|
||||||
|
@override
|
||||||
|
TextColumnBuilder named(String name) => this;
|
||||||
|
@override
|
||||||
|
TextColumnBuilder primaryKey() => this;
|
||||||
|
// @override
|
||||||
|
// TextColumnBuilder references<Table>(Column<String> extractor(Table table)) => this;
|
||||||
|
@override
|
||||||
|
TextColumn call() => null;
|
||||||
|
|
||||||
|
TextColumnBuilder withLength({int min, int max}) => this;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:sally/sally.dart';
|
||||||
|
|
||||||
|
abstract class Table {
|
||||||
|
const Table();
|
||||||
|
|
||||||
|
@visibleForOverriding
|
||||||
|
String get tableName => null;
|
||||||
|
|
||||||
|
@visibleForOverriding
|
||||||
|
// todo allow custom primary key
|
||||||
|
PrimaryKey get primaryKey => null;
|
||||||
|
|
||||||
|
@protected
|
||||||
|
IntColumnBuilder integer() => null;
|
||||||
|
@protected
|
||||||
|
TextColumnBuilder text() => null;
|
||||||
|
@protected
|
||||||
|
BoolColumnBuilder boolean() => null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PrimaryKey {}
|
|
@ -0,0 +1,10 @@
|
||||||
|
export 'package:sally/src/queries/generation_context.dart';
|
||||||
|
export 'package:sally/src/queries/expressions/limit.dart';
|
||||||
|
export 'package:sally/src/queries/expressions/variable.dart';
|
||||||
|
export 'package:sally/src/queries/expressions/where.dart';
|
||||||
|
|
||||||
|
import 'package:sally/src/queries/expressions/expressions.dart';
|
||||||
|
|
||||||
|
abstract class SqlExpression {
|
||||||
|
void writeInto(GenerationContext context);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import 'package:sally/src/queries/expressions/expressions.dart';
|
||||||
|
import 'package:sally/src/queries/generation_context.dart';
|
||||||
|
|
||||||
|
class LimitExpression extends SqlExpression {
|
||||||
|
final int amount;
|
||||||
|
final int offset;
|
||||||
|
|
||||||
|
LimitExpression(this.amount, this.offset);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeInto(GenerationContext context) {
|
||||||
|
if (offset != null)
|
||||||
|
context.buffer.write('LIMIT $amount, $offset ');
|
||||||
|
else
|
||||||
|
context.buffer.write('LIMIT $amount ');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import 'package:sally/src/queries/expressions/expressions.dart';
|
||||||
|
import 'package:sally/src/queries/generation_context.dart';
|
||||||
|
|
||||||
|
class Variable extends SqlExpression {
|
||||||
|
final dynamic value;
|
||||||
|
|
||||||
|
Variable(this.value);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeInto(GenerationContext context) {
|
||||||
|
context.addBoundVariable(value);
|
||||||
|
|
||||||
|
context.buffer.write('? ');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import 'package:sally/src/queries/expressions/expressions.dart';
|
||||||
|
import 'package:sally/src/queries/generation_context.dart';
|
||||||
|
import 'package:sally/src/queries/predicates/predicate.dart';
|
||||||
|
|
||||||
|
class WhereExpression extends SqlExpression {
|
||||||
|
final Predicate predicate;
|
||||||
|
|
||||||
|
WhereExpression(this.predicate);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeInto(GenerationContext context) {
|
||||||
|
context.buffer.write("WHERE ");
|
||||||
|
predicate.writeInto(context);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
class GenerationContext {
|
||||||
|
StringBuffer buffer = StringBuffer();
|
||||||
|
List<dynamic> boundVariables = List();
|
||||||
|
|
||||||
|
void addBoundVariable(dynamic data) {
|
||||||
|
boundVariables.add(data);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
import 'package:sally/src/queries/generation_context.dart';
|
||||||
|
import 'package:sally/src/queries/predicates/predicate.dart';
|
||||||
|
|
||||||
|
class NotPredicate extends Predicate {
|
||||||
|
final Predicate inner;
|
||||||
|
|
||||||
|
NotPredicate(this.inner);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeInto(GenerationContext context) {
|
||||||
|
context.buffer.write("NOT ");
|
||||||
|
inner.writeInto(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OrPredicate extends Predicate {
|
||||||
|
final Predicate a, b;
|
||||||
|
|
||||||
|
OrPredicate(this.a, this.b);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeInto(GenerationContext context) {
|
||||||
|
context.buffer.write('(');
|
||||||
|
a.writeInto(context);
|
||||||
|
context.buffer.write(') OR ( ');
|
||||||
|
b.writeInto(context);
|
||||||
|
context.buffer.write(') ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AndPredicate extends Predicate {
|
||||||
|
final Predicate a, b;
|
||||||
|
|
||||||
|
AndPredicate(this.a, this.b);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeInto(GenerationContext context) {
|
||||||
|
context.buffer.write('(');
|
||||||
|
a.writeInto(context);
|
||||||
|
context.buffer.write(') AND (');
|
||||||
|
b.writeInto(context);
|
||||||
|
context.buffer.write(') ');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
import 'package:sally/src/queries/expressions/expressions.dart';
|
||||||
|
import 'package:sally/src/queries/generation_context.dart';
|
||||||
|
import 'package:sally/src/queries/predicates/predicate.dart';
|
||||||
|
|
||||||
|
enum ComparisonOperator { less, less_or_equal, more, more_or_equal }
|
||||||
|
|
||||||
|
class NumberComparisonPredicate extends Predicate {
|
||||||
|
static const Map<ComparisonOperator, String> _operators = {
|
||||||
|
ComparisonOperator.less: '< ',
|
||||||
|
ComparisonOperator.less_or_equal: '<= ',
|
||||||
|
ComparisonOperator.more: '> ',
|
||||||
|
ComparisonOperator.more_or_equal: '>= ',
|
||||||
|
};
|
||||||
|
|
||||||
|
SqlExpression left;
|
||||||
|
ComparisonOperator operator;
|
||||||
|
SqlExpression right;
|
||||||
|
|
||||||
|
NumberComparisonPredicate(this.left, this.operator, this.right);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeInto(GenerationContext context) {
|
||||||
|
left.writeInto(context);
|
||||||
|
context.buffer.write(_operators[operator]);
|
||||||
|
right.writeInto(context);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
export 'package:sally/src/queries/predicates/combining.dart';
|
||||||
|
export 'package:sally/src/queries/predicates/numbers.dart';
|
||||||
|
export 'package:sally/src/queries/predicates/text.dart';
|
||||||
|
|
||||||
|
import 'package:sally/src/queries/expressions/expressions.dart';
|
||||||
|
import 'package:sally/src/queries/generation_context.dart';
|
||||||
|
import 'package:sally/src/queries/predicates/combining.dart';
|
||||||
|
|
||||||
|
Predicate not(Predicate p) => p.not();
|
||||||
|
|
||||||
|
abstract class Predicate extends SqlExpression {
|
||||||
|
Predicate not() {
|
||||||
|
return NotPredicate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate and(Predicate other) => AndPredicate(this, other);
|
||||||
|
Predicate or(Predicate other) => OrPredicate(this, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EqualityPredicate extends Predicate {
|
||||||
|
SqlExpression left;
|
||||||
|
SqlExpression right;
|
||||||
|
|
||||||
|
EqualityPredicate(this.left, this.right);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeInto(GenerationContext context) {
|
||||||
|
left.writeInto(context);
|
||||||
|
context.buffer.write('= ');
|
||||||
|
right.writeInto(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BooleanExpressionPredicate extends Predicate {
|
||||||
|
SqlExpression expression;
|
||||||
|
|
||||||
|
BooleanExpressionPredicate(this.expression);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeInto(GenerationContext context) {
|
||||||
|
expression.writeInto(context);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import 'package:sally/src/queries/expressions/expressions.dart';
|
||||||
|
import 'package:sally/src/queries/generation_context.dart';
|
||||||
|
import 'package:sally/src/queries/predicates/predicate.dart';
|
||||||
|
|
||||||
|
class LikePredicate extends Predicate {
|
||||||
|
SqlExpression target;
|
||||||
|
SqlExpression regex;
|
||||||
|
|
||||||
|
LikePredicate(this.target, this.regex);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeInto(GenerationContext context) {
|
||||||
|
target.writeInto(context);
|
||||||
|
context.buffer.write('LIKE ');
|
||||||
|
regex.writeInto(context);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
import 'package:sally/src/queries/expressions/limit.dart';
|
||||||
|
import 'package:sally/src/queries/expressions/where.dart';
|
||||||
|
import 'package:sally/src/queries/generation_context.dart';
|
||||||
|
import 'package:sally/src/queries/predicates/predicate.dart';
|
||||||
|
import 'package:sally/src/queries/table_structure.dart';
|
||||||
|
|
||||||
|
abstract class SqlStatement {
|
||||||
|
GenerationContext _buildQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class StatementForExistingData<Table, Result> extends SqlStatement {
|
||||||
|
final TableStructure<Table, Result> _table;
|
||||||
|
|
||||||
|
StatementForExistingData(this._table);
|
||||||
|
|
||||||
|
WhereExpression _where;
|
||||||
|
LimitExpression _limit;
|
||||||
|
|
||||||
|
Future<List<Result>> get() async {
|
||||||
|
final ctx = _buildQuery();
|
||||||
|
final sql = ctx.buffer.toString();
|
||||||
|
final vars = ctx.boundVariables;
|
||||||
|
|
||||||
|
final result = await _table.executor.executeQuery(sql, vars);
|
||||||
|
return result.map(_table.parse).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Result> single() async {
|
||||||
|
// limit to one item, using the existing offset if it exists
|
||||||
|
_limit = LimitExpression(1, _limit?.offset ?? 0);
|
||||||
|
|
||||||
|
return (await get()).single;
|
||||||
|
}
|
||||||
|
|
||||||
|
StatementForExistingData<Table, Result> where(
|
||||||
|
Predicate extractor(Table tbl)) {
|
||||||
|
final addedPredicate = extractor(_table.asTable);
|
||||||
|
|
||||||
|
if (_where != null) {
|
||||||
|
// merge existing where expression together with new one by and-ing them
|
||||||
|
// together.
|
||||||
|
_where = WhereExpression(_where.predicate.and(addedPredicate));
|
||||||
|
} else {
|
||||||
|
_where = WhereExpression(addedPredicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
StatementForExistingData<Table, Result> limit({int amount, int offset}) {
|
||||||
|
_limit = LimitExpression(amount, offset);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SelectStatement<T, R> extends StatementForExistingData<T, R> {
|
||||||
|
SelectStatement(TableStructure<T, R> table) : super(table);
|
||||||
|
|
||||||
|
@override
|
||||||
|
GenerationContext _buildQuery() {
|
||||||
|
GenerationContext context = GenerationContext();
|
||||||
|
context.buffer.write('SELECT * FROM ');
|
||||||
|
context.buffer.write(_table.sqlTableName);
|
||||||
|
context.buffer.write(' ');
|
||||||
|
|
||||||
|
if (_where != null) _where.writeInto(context);
|
||||||
|
if (_limit != null) _limit.writeInto(context);
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
import 'package:sally/sally.dart';
|
||||||
|
import 'package:sally/src/dsl/columns.dart';
|
||||||
|
import 'package:sally/src/queries/expressions/expressions.dart';
|
||||||
|
import 'package:sally/src/queries/expressions/variable.dart';
|
||||||
|
import 'package:sally/src/queries/generation_context.dart';
|
||||||
|
import 'package:sally/src/queries/predicates/numbers.dart';
|
||||||
|
import 'package:sally/src/queries/predicates/predicate.dart';
|
||||||
|
import 'package:sally/src/queries/predicates/text.dart';
|
||||||
|
import 'package:sally/src/queries/statements.dart';
|
||||||
|
|
||||||
|
abstract class TableStructure<UserSpecifiedTable, ResolvedType> {
|
||||||
|
QueryExecutor executor;
|
||||||
|
|
||||||
|
UserSpecifiedTable get asTable;
|
||||||
|
String get sqlTableName;
|
||||||
|
|
||||||
|
ResolvedType parse(Map<String, dynamic> result);
|
||||||
|
|
||||||
|
SelectStatement<UserSpecifiedTable, ResolvedType> select() =>
|
||||||
|
SelectStatement<UserSpecifiedTable, ResolvedType>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class StructuredColumn<T> implements SqlExpression, Column<T> {
|
||||||
|
final String sqlName;
|
||||||
|
|
||||||
|
StructuredColumn(this.sqlName);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void writeInto(GenerationContext context) {
|
||||||
|
// todo table name lookup, as-expressions etc?
|
||||||
|
context.buffer.write(sqlName);
|
||||||
|
context.buffer.write(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Predicate equals(T compare) => EqualityPredicate(this, Variable(compare));
|
||||||
|
}
|
||||||
|
|
||||||
|
class StructuredIntColumn extends StructuredColumn<int> implements IntColumn {
|
||||||
|
StructuredIntColumn(String sqlName) : super(sqlName);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Predicate isBiggerThan(int i) =>
|
||||||
|
NumberComparisonPredicate(this, ComparisonOperator.more, Variable(i));
|
||||||
|
@override
|
||||||
|
Predicate isSmallerThan(int i) =>
|
||||||
|
NumberComparisonPredicate(this, ComparisonOperator.less, Variable(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
class StructuredBoolColumn extends StructuredColumn<bool>
|
||||||
|
implements BoolColumn {
|
||||||
|
StructuredBoolColumn(String sqlName) : super(sqlName);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Predicate isFalse() {
|
||||||
|
return not(isTrue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Predicate isTrue() {
|
||||||
|
return BooleanExpressionPredicate(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StructuredTextColumn extends StructuredColumn<String>
|
||||||
|
implements TextColumn {
|
||||||
|
StructuredTextColumn(String sqlName) : super(sqlName);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Predicate like(String regex) => LikePredicate(this, Variable(regex));
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
dart:
|
||||||
|
- stable
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- analyze:
|
||||||
|
- dartanalyzer
|
||||||
|
- dartfmt
|
||||||
|
- unit_test:
|
||||||
|
- test
|
|
@ -0,0 +1,15 @@
|
||||||
|
name: sally
|
||||||
|
description: A starting point for Dart libraries or applications.
|
||||||
|
# version: 1.0.0
|
||||||
|
# homepage: https://www.example.com
|
||||||
|
# author: Simon Binder <email@example.com>
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.1.0 <3.0.0'
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
meta: '>= 1.0.0 <2.0.0'
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
mockito: ^4.0.0
|
||||||
|
test: ^1.0.0
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/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>
|
|
@ -0,0 +1,80 @@
|
||||||
|
import 'package:sally/sally.dart';
|
||||||
|
import 'package:sally/src/queries/predicates/predicate.dart';
|
||||||
|
import 'package:sally/src/queries/table_structure.dart';
|
||||||
|
import 'package:test_api/test_api.dart';
|
||||||
|
import 'package:mockito/mockito.dart';
|
||||||
|
|
||||||
|
class MockExecutor extends Mock implements QueryExecutor {}
|
||||||
|
|
||||||
|
class Users extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
TextColumn get name => text().withLength(min: 6, max: 32)();
|
||||||
|
BoolColumn get isAwesome => boolean()();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example tables and data classes, these would be generated by sally_generator
|
||||||
|
// in a real project
|
||||||
|
class UserDataObject {
|
||||||
|
final int id;
|
||||||
|
final String name;
|
||||||
|
UserDataObject(this.id, this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
class GeneratedUsersTable extends Users
|
||||||
|
with TableStructure<Users, UserDataObject> {
|
||||||
|
@override
|
||||||
|
Users get asTable => this;
|
||||||
|
@override
|
||||||
|
UserDataObject parse(Map<String, dynamic> result) {
|
||||||
|
return UserDataObject(result["id"], result["name"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sqlTableName => "users";
|
||||||
|
|
||||||
|
IntColumn id = StructuredIntColumn("id");
|
||||||
|
TextColumn name = StructuredTextColumn("name");
|
||||||
|
BoolColumn isAwesome = StructuredBoolColumn("is_awesome");
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
GeneratedUsersTable users;
|
||||||
|
MockExecutor executor;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
users = GeneratedUsersTable();
|
||||||
|
executor = MockExecutor();
|
||||||
|
users.executor = executor;
|
||||||
|
|
||||||
|
when(executor.executeQuery(any, any)).thenAnswer((_) => Future.value([]));
|
||||||
|
});
|
||||||
|
|
||||||
|
group("Generates SELECT statements", () {
|
||||||
|
test("generates simple statements", () {
|
||||||
|
users.select().get();
|
||||||
|
verify(executor.executeQuery("SELECT * FROM users ", any));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("generates limit statements", () {
|
||||||
|
users.select().limit(amount: 10).get();
|
||||||
|
verify(executor.executeQuery("SELECT * FROM users LIMIT 10 ", any));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("generates like expressions", () {
|
||||||
|
users.select().where((u) => u.name.like("Dash%")).get();
|
||||||
|
verify(executor
|
||||||
|
.executeQuery("SELECT * FROM users WHERE name LIKE ? ", ["Dash%"]));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("generates complex predicates", () {
|
||||||
|
users
|
||||||
|
.select()
|
||||||
|
.where((u) => not(u.name.equals("Dash")).and(u.id.isBiggerThan(12)))
|
||||||
|
.get();
|
||||||
|
|
||||||
|
verify(executor.executeQuery(
|
||||||
|
"SELECT * FROM users WHERE (NOT name = ? ) AND (id > ? ) ",
|
||||||
|
["Dash", 12]));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
## 1.0.0
|
||||||
|
|
||||||
|
- Initial version, created by Stagehand
|
|
@ -0,0 +1,22 @@
|
||||||
|
A library for Dart developers.
|
||||||
|
|
||||||
|
Created from templates made available by Stagehand under a BSD-style
|
||||||
|
[license](https://github.com/dart-lang/stagehand/blob/master/LICENSE).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
A simple usage example:
|
||||||
|
|
||||||
|
```dart
|
||||||
|
import 'package:sally_generator/sally_generator.dart';
|
||||||
|
|
||||||
|
main() {
|
||||||
|
var awesome = new Awesome();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features and bugs
|
||||||
|
|
||||||
|
Please file feature requests and bugs at the [issue tracker][tracker].
|
||||||
|
|
||||||
|
[tracker]: http://example.com/issues/replaceme
|
|
@ -0,0 +1,8 @@
|
||||||
|
#builders:
|
||||||
|
# sally_generator:
|
||||||
|
# import: "package:sally_generator/generator.dart"
|
||||||
|
# builder_factories: ["sallyBuilder"]
|
||||||
|
# build_extensions: {".dart": [".sally.g.part"]}
|
||||||
|
# auto_apply: dependents
|
||||||
|
# build_to: cache
|
||||||
|
# applies_builders: ["source_gen|combining_builder"]
|
|
@ -0,0 +1,6 @@
|
||||||
|
import 'package:build/build.dart';
|
||||||
|
import 'package:source_gen/source_gen.dart';
|
||||||
|
import 'package:sally_generator/src/sally_generator.dart';
|
||||||
|
|
||||||
|
Builder sallyBuilder(BuilderOptions _) =>
|
||||||
|
new SharedPartBuilder([SallyGenerator()], "sally");
|
|
@ -0,0 +1,18 @@
|
||||||
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
|
||||||
|
class SallyError {
|
||||||
|
final bool critical;
|
||||||
|
final String message;
|
||||||
|
final Element affectedElement;
|
||||||
|
|
||||||
|
SallyError(
|
||||||
|
{this.critical = false, this.message, this.affectedElement = null});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ErrorStore {
|
||||||
|
final List<SallyError> errors = [];
|
||||||
|
|
||||||
|
void add(SallyError error) => errors.add(error);
|
||||||
|
|
||||||
|
bool get hasCriticalError => errors.any((e) => e.critical);
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
import 'package:built_value/built_value.dart';
|
||||||
|
|
||||||
|
part 'specified_column.g.dart';
|
||||||
|
|
||||||
|
enum ColumnType { integer, text, boolean }
|
||||||
|
|
||||||
|
abstract class ColumnName implements Built<ColumnName, ColumnNameBuilder> {
|
||||||
|
/// A column name is implicit if it has been looked up with the associated
|
||||||
|
/// field name in the table class. It's explicit if `.named()` was called in
|
||||||
|
/// the column builder.
|
||||||
|
bool get implicit;
|
||||||
|
String get name;
|
||||||
|
|
||||||
|
ColumnName._();
|
||||||
|
factory ColumnName([updates(ColumnNameBuilder b)]) = _$ColumnName;
|
||||||
|
|
||||||
|
factory ColumnName.implicitly(String name) => ColumnName((b) => b
|
||||||
|
..implicit = true
|
||||||
|
..name = name);
|
||||||
|
factory ColumnName.explicitly(String name) => ColumnName((b) => b
|
||||||
|
..implicit = false
|
||||||
|
..name = name);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SpecifiedColumn {
|
||||||
|
final ColumnType type;
|
||||||
|
final ColumnName name;
|
||||||
|
|
||||||
|
bool get hasAI => features.any((f) => f is AutoIncrement);
|
||||||
|
|
||||||
|
/// Whether this column has been declared as the primary key via the
|
||||||
|
/// column builder. The `primaryKey` field in the table class is unrelated to
|
||||||
|
/// this.
|
||||||
|
final bool declaredAsPrimaryKey;
|
||||||
|
final List<ColumnFeature> features;
|
||||||
|
|
||||||
|
const SpecifiedColumn(
|
||||||
|
{this.type,
|
||||||
|
this.name,
|
||||||
|
this.declaredAsPrimaryKey = false,
|
||||||
|
this.features = const []});
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ColumnFeature {
|
||||||
|
const ColumnFeature();
|
||||||
|
}
|
||||||
|
|
||||||
|
class AutoIncrement extends ColumnFeature {
|
||||||
|
static const AutoIncrement _instance = AutoIncrement._();
|
||||||
|
|
||||||
|
const AutoIncrement._();
|
||||||
|
|
||||||
|
factory AutoIncrement() => _instance;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(other) => other is AutoIncrement;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class LimitingTextLength extends ColumnFeature
|
||||||
|
implements Built<LimitingTextLength, LimitingTextLengthBuilder> {
|
||||||
|
@nullable
|
||||||
|
int get minLength;
|
||||||
|
@nullable
|
||||||
|
int get maxLength;
|
||||||
|
|
||||||
|
LimitingTextLength._();
|
||||||
|
factory LimitingTextLength(void updates(LimitingTextLengthBuilder b)) =
|
||||||
|
_$LimitingTextLength;
|
||||||
|
|
||||||
|
factory LimitingTextLength.withLength({int min, int max}) =>
|
||||||
|
LimitingTextLength((b) => b
|
||||||
|
..minLength = min
|
||||||
|
..maxLength = max);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Reference extends ColumnFeature {
|
||||||
|
final SpecifiedColumn referencedColumn;
|
||||||
|
|
||||||
|
const Reference(this.referencedColumn);
|
||||||
|
}
|
|
@ -0,0 +1,185 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'specified_column.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// BuiltValueGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
class _$ColumnName extends ColumnName {
|
||||||
|
@override
|
||||||
|
final bool implicit;
|
||||||
|
@override
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
factory _$ColumnName([void updates(ColumnNameBuilder b)]) =>
|
||||||
|
(new ColumnNameBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$ColumnName._({this.implicit, this.name}) : super._() {
|
||||||
|
if (implicit == null) {
|
||||||
|
throw new BuiltValueNullFieldError('ColumnName', 'implicit');
|
||||||
|
}
|
||||||
|
if (name == null) {
|
||||||
|
throw new BuiltValueNullFieldError('ColumnName', 'name');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ColumnName rebuild(void updates(ColumnNameBuilder b)) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
ColumnNameBuilder toBuilder() => new ColumnNameBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is ColumnName &&
|
||||||
|
implicit == other.implicit &&
|
||||||
|
name == other.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc($jc(0, implicit.hashCode), name.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('ColumnName')
|
||||||
|
..add('implicit', implicit)
|
||||||
|
..add('name', name))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColumnNameBuilder implements Builder<ColumnName, ColumnNameBuilder> {
|
||||||
|
_$ColumnName _$v;
|
||||||
|
|
||||||
|
bool _implicit;
|
||||||
|
bool get implicit => _$this._implicit;
|
||||||
|
set implicit(bool implicit) => _$this._implicit = implicit;
|
||||||
|
|
||||||
|
String _name;
|
||||||
|
String get name => _$this._name;
|
||||||
|
set name(String name) => _$this._name = name;
|
||||||
|
|
||||||
|
ColumnNameBuilder();
|
||||||
|
|
||||||
|
ColumnNameBuilder get _$this {
|
||||||
|
if (_$v != null) {
|
||||||
|
_implicit = _$v.implicit;
|
||||||
|
_name = _$v.name;
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(ColumnName other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$ColumnName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void updates(ColumnNameBuilder b)) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$ColumnName build() {
|
||||||
|
final _$result = _$v ?? new _$ColumnName._(implicit: implicit, name: name);
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _$LimitingTextLength extends LimitingTextLength {
|
||||||
|
@override
|
||||||
|
final int minLength;
|
||||||
|
@override
|
||||||
|
final int maxLength;
|
||||||
|
|
||||||
|
factory _$LimitingTextLength([void updates(LimitingTextLengthBuilder b)]) =>
|
||||||
|
(new LimitingTextLengthBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
_$LimitingTextLength._({this.minLength, this.maxLength}) : super._();
|
||||||
|
|
||||||
|
@override
|
||||||
|
LimitingTextLength rebuild(void updates(LimitingTextLengthBuilder b)) =>
|
||||||
|
(toBuilder()..update(updates)).build();
|
||||||
|
|
||||||
|
@override
|
||||||
|
LimitingTextLengthBuilder toBuilder() =>
|
||||||
|
new LimitingTextLengthBuilder()..replace(this);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(other, this)) return true;
|
||||||
|
return other is LimitingTextLength &&
|
||||||
|
minLength == other.minLength &&
|
||||||
|
maxLength == other.maxLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return $jf($jc($jc(0, minLength.hashCode), maxLength.hashCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (newBuiltValueToStringHelper('LimitingTextLength')
|
||||||
|
..add('minLength', minLength)
|
||||||
|
..add('maxLength', maxLength))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LimitingTextLengthBuilder
|
||||||
|
implements Builder<LimitingTextLength, LimitingTextLengthBuilder> {
|
||||||
|
_$LimitingTextLength _$v;
|
||||||
|
|
||||||
|
int _minLength;
|
||||||
|
int get minLength => _$this._minLength;
|
||||||
|
set minLength(int minLength) => _$this._minLength = minLength;
|
||||||
|
|
||||||
|
int _maxLength;
|
||||||
|
int get maxLength => _$this._maxLength;
|
||||||
|
set maxLength(int maxLength) => _$this._maxLength = maxLength;
|
||||||
|
|
||||||
|
LimitingTextLengthBuilder();
|
||||||
|
|
||||||
|
LimitingTextLengthBuilder get _$this {
|
||||||
|
if (_$v != null) {
|
||||||
|
_minLength = _$v.minLength;
|
||||||
|
_maxLength = _$v.maxLength;
|
||||||
|
_$v = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(LimitingTextLength other) {
|
||||||
|
if (other == null) {
|
||||||
|
throw new ArgumentError.notNull('other');
|
||||||
|
}
|
||||||
|
_$v = other as _$LimitingTextLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void update(void updates(LimitingTextLengthBuilder b)) {
|
||||||
|
if (updates != null) updates(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_$LimitingTextLength build() {
|
||||||
|
final _$result = _$v ??
|
||||||
|
new _$LimitingTextLength._(minLength: minLength, maxLength: maxLength);
|
||||||
|
replace(_$result);
|
||||||
|
return _$result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore_for_file: always_put_control_body_on_new_line,annotate_overrides,avoid_annotating_with_dynamic,avoid_as,avoid_catches_without_on_clauses,avoid_returning_this,lines_longer_than_80_chars,omit_local_variable_types,prefer_expression_function_bodies,sort_constructors_first,test_types_in_equals,unnecessary_const,unnecessary_new
|
|
@ -0,0 +1,12 @@
|
||||||
|
import 'package:sally_generator/src/model/specified_column.dart';
|
||||||
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
|
||||||
|
class SpecifiedTable {
|
||||||
|
final ClassElement fromClass;
|
||||||
|
final List<SpecifiedColumn> columns;
|
||||||
|
final String sqlName;
|
||||||
|
final String dartTypeName;
|
||||||
|
|
||||||
|
const SpecifiedTable(
|
||||||
|
{this.fromClass, this.columns, this.sqlName, this.dartTypeName});
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
import 'package:analyzer/dart/ast/ast.dart';
|
||||||
|
import 'package:sally_generator/src/errors.dart';
|
||||||
|
import 'package:sally_generator/src/model/specified_column.dart';
|
||||||
|
import 'package:sally_generator/src/parser/parser.dart';
|
||||||
|
import 'package:sally_generator/src/sally_generator.dart';
|
||||||
|
|
||||||
|
const String startInt = "integer";
|
||||||
|
const String startString = "text";
|
||||||
|
const String startBool = "boolean";
|
||||||
|
|
||||||
|
// todo replace with set literal once dart supports it
|
||||||
|
final Set<String> starters = [startInt, startString, startBool].toSet();
|
||||||
|
|
||||||
|
const String functionNamed = "named";
|
||||||
|
const String functionPrimaryKey = "primaryKey";
|
||||||
|
const String functionReferences = "references";
|
||||||
|
const String functionAutoIncrement = "autoIncrement";
|
||||||
|
const String functionWithLength = "withLength";
|
||||||
|
|
||||||
|
const String errorMessage = "This getter does not create a valid column that "
|
||||||
|
"can be parsed by sally. Please refer to the readme from sally to see how "
|
||||||
|
"columns are formed. If you have any questions, feel free to raise an issue.";
|
||||||
|
|
||||||
|
class ColumnParser extends ParserBase {
|
||||||
|
ColumnParser(SallyGenerator generator) : super(generator);
|
||||||
|
|
||||||
|
SpecifiedColumn parse(MethodDeclaration getter) {
|
||||||
|
/*
|
||||||
|
These getters look like this: ... get id => integer().autoIncrement()();
|
||||||
|
The last () is a FunctionExpressionInvocation, the entries before that
|
||||||
|
(here autoIncrement and integer) are MethodInvocations.
|
||||||
|
We go through each of the method invocations until we hit one that starts
|
||||||
|
the chain (integer, text, boolean, etc.). From each method in the chain,
|
||||||
|
we can extract what it means for the column (name, auto increment, PK,
|
||||||
|
constraints...).
|
||||||
|
*/
|
||||||
|
final expr = returnExpressionOfMethod(getter);
|
||||||
|
|
||||||
|
if (!(expr is FunctionExpressionInvocation)) {
|
||||||
|
generator.errors.add(SallyError(
|
||||||
|
affectedElement: getter.declaredElement,
|
||||||
|
message: errorMessage,
|
||||||
|
critical: true,
|
||||||
|
));
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var remainingExpr =
|
||||||
|
(expr as FunctionExpressionInvocation).function as MethodInvocation;
|
||||||
|
|
||||||
|
String foundStartMethod;
|
||||||
|
String foundExplicitName;
|
||||||
|
bool wasDeclaredAsPrimaryKey = false;
|
||||||
|
// todo parse reference
|
||||||
|
List<ColumnFeature> foundFeatures = [];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
final methodName = remainingExpr.methodName.name;
|
||||||
|
|
||||||
|
if (starters.contains(methodName)) {
|
||||||
|
foundStartMethod = methodName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (methodName) {
|
||||||
|
case functionNamed:
|
||||||
|
if (foundExplicitName != null) {
|
||||||
|
generator.errors.add(SallyError(
|
||||||
|
critical: false,
|
||||||
|
affectedElement: getter.declaredElement,
|
||||||
|
message:
|
||||||
|
"You're setting more than one name here, the first will "
|
||||||
|
"be used"));
|
||||||
|
}
|
||||||
|
|
||||||
|
foundExplicitName =
|
||||||
|
readStringLiteral(remainingExpr.argumentList.arguments.first, () {
|
||||||
|
generator.errors.add(SallyError(
|
||||||
|
critical: false,
|
||||||
|
affectedElement: getter.declaredElement,
|
||||||
|
message:
|
||||||
|
"This table name is cannot be resolved! Please only use "
|
||||||
|
"a constant string as parameter for .named()."));
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case functionPrimaryKey:
|
||||||
|
wasDeclaredAsPrimaryKey = true;
|
||||||
|
break;
|
||||||
|
case functionReferences:
|
||||||
|
break; // todo: parsing this is going to suck
|
||||||
|
case functionWithLength:
|
||||||
|
final args = remainingExpr.argumentList;
|
||||||
|
final minArg = findNamedArgument(args, "min");
|
||||||
|
final maxArg = findNamedArgument(args, "max");
|
||||||
|
|
||||||
|
foundFeatures.add(LimitingTextLength.withLength(
|
||||||
|
min: readIntLiteral(minArg, () {}),
|
||||||
|
max: readIntLiteral(maxArg, () {}),
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case functionAutoIncrement:
|
||||||
|
wasDeclaredAsPrimaryKey = true;
|
||||||
|
foundFeatures.add(AutoIncrement());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're not at a starting method yet, so we need to go deeper!
|
||||||
|
final inner = (remainingExpr.target) as MethodInvocation;
|
||||||
|
remainingExpr = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnName name;
|
||||||
|
if (foundExplicitName != null) {
|
||||||
|
name = ColumnName.explicitly(foundExplicitName);
|
||||||
|
} else {
|
||||||
|
name = ColumnName.implicitly(getter.name.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SpecifiedColumn(
|
||||||
|
type: _startMethodToColumnType(foundStartMethod),
|
||||||
|
name: name,
|
||||||
|
declaredAsPrimaryKey: wasDeclaredAsPrimaryKey,
|
||||||
|
features: foundFeatures);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnType _startMethodToColumnType(String startMethod) {
|
||||||
|
return const {
|
||||||
|
startBool: ColumnType.boolean,
|
||||||
|
startString: ColumnType.text,
|
||||||
|
startInt: ColumnType.integer,
|
||||||
|
}[startMethod];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
import 'package:analyzer/dart/ast/ast.dart';
|
||||||
|
import 'package:sally_generator/src/errors.dart';
|
||||||
|
import 'package:sally_generator/src/model/specified_table.dart';
|
||||||
|
import 'package:sally_generator/src/sally_generator.dart';
|
||||||
|
|
||||||
|
class Parser {
|
||||||
|
List<SpecifiedTable> specifiedTables;
|
||||||
|
|
||||||
|
void init() async {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ParserBase {
|
||||||
|
final SallyGenerator generator;
|
||||||
|
|
||||||
|
ParserBase(this.generator);
|
||||||
|
|
||||||
|
Expression returnExpressionOfMethod(MethodDeclaration method) {
|
||||||
|
final body = method.body;
|
||||||
|
|
||||||
|
if (!(body is ExpressionFunctionBody)) {
|
||||||
|
generator.errors.add(SallyError(
|
||||||
|
affectedElement: method.declaredElement,
|
||||||
|
critical: true,
|
||||||
|
message:
|
||||||
|
"This method must have an expression body (use => instead of {return ...})"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (method.body as ExpressionFunctionBody).expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
String readStringLiteral(Expression expression, void onError()) {
|
||||||
|
if (!(expression is StringLiteral)) {
|
||||||
|
onError();
|
||||||
|
} else {
|
||||||
|
String value = (expression as StringLiteral).stringValue;
|
||||||
|
if (value == null)
|
||||||
|
onError();
|
||||||
|
else
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int readIntLiteral(Expression expression, void onError()) {
|
||||||
|
if (!(expression is IntegerLiteral)) {
|
||||||
|
onError();
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return (expression as IntegerLiteral).value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression findNamedArgument(ArgumentList args, String argName) {
|
||||||
|
final argument = args.arguments.singleWhere(
|
||||||
|
(e) => e is NamedExpression && e.name.label.name == argName,
|
||||||
|
orElse: () => null) as NamedExpression;
|
||||||
|
|
||||||
|
return argument?.expression;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
import 'package:analyzer/dart/ast/ast.dart';
|
||||||
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
import 'package:sally_generator/src/errors.dart';
|
||||||
|
import 'package:sally_generator/src/model/specified_column.dart';
|
||||||
|
import 'package:sally_generator/src/model/specified_table.dart';
|
||||||
|
import 'package:sally_generator/src/parser/parser.dart';
|
||||||
|
import 'package:sally_generator/src/utils/type_utils.dart';
|
||||||
|
import 'package:sally_generator/src/sally_generator.dart'; // ignore: implementation_imports
|
||||||
|
import 'package:recase/recase.dart';
|
||||||
|
|
||||||
|
class TableParser extends ParserBase {
|
||||||
|
TableParser(SallyGenerator generator) : super(generator);
|
||||||
|
|
||||||
|
SpecifiedTable parse(ClassElement element) {
|
||||||
|
String sqlName = _parseTableName(element);
|
||||||
|
|
||||||
|
return SpecifiedTable(
|
||||||
|
fromClass: element,
|
||||||
|
columns: _parseColumns(element),
|
||||||
|
sqlName: sqlName,
|
||||||
|
dartTypeName:
|
||||||
|
"${element.name}_Data" // TODO better name for generated data classes
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _parseTableName(ClassElement element) {
|
||||||
|
final tableNameGetter = element.getGetter("tableName");
|
||||||
|
if (tableNameGetter == null) {
|
||||||
|
// class does not override tableName. So just use the dart class name
|
||||||
|
// instead. Will use placed_orders for a class called PlacedOrders
|
||||||
|
return ReCase(element.name).snakeCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we expect something like get tableName => "myTableName", the getter
|
||||||
|
// must do nothing more complicated
|
||||||
|
final tableNameDeclaration =
|
||||||
|
generator.loadElementDeclaration(tableNameGetter);
|
||||||
|
final returnExpr = returnExpressionOfMethod(
|
||||||
|
tableNameDeclaration.node as MethodDeclaration);
|
||||||
|
|
||||||
|
String tableName = readStringLiteral(returnExpr, () {
|
||||||
|
generator.errors.add(SallyError(
|
||||||
|
critical: true,
|
||||||
|
message:
|
||||||
|
"This getter must return a string literal, and do nothing more",
|
||||||
|
affectedElement: tableNameGetter));
|
||||||
|
});
|
||||||
|
|
||||||
|
return tableName;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable<MethodDeclaration> _findColumnGetters(ClassElement element) {
|
||||||
|
return element.fields
|
||||||
|
.where((field) => isColumn(field.type) && field.getter != null)
|
||||||
|
.map((field) {
|
||||||
|
var node = generator.loadElementDeclaration(field.getter).node;
|
||||||
|
|
||||||
|
return node as MethodDeclaration;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SpecifiedColumn _parseColumn(MethodDeclaration getter) {
|
||||||
|
return generator.columnParser.parse(getter);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<SpecifiedColumn> _parseColumns(ClassElement element) =>
|
||||||
|
_findColumnGetters(element).map(_parseColumn).toList();
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
import 'package:analyzer/dart/analysis/results.dart';
|
||||||
|
import 'package:analyzer/src/dart/analysis/results.dart'; // ignore: implementation_imports
|
||||||
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
import 'package:build/build.dart';
|
||||||
|
import 'package:sally_generator/src/errors.dart';
|
||||||
|
import 'package:sally_generator/src/parser/column_parser.dart';
|
||||||
|
import 'package:sally_generator/src/parser/table_parser.dart';
|
||||||
|
import 'package:source_gen/source_gen.dart';
|
||||||
|
|
||||||
|
class SallyGenerator extends Generator {
|
||||||
|
Map<String, ParsedLibraryResult> _astForLibs = Map();
|
||||||
|
ErrorStore errors = ErrorStore();
|
||||||
|
|
||||||
|
TableParser tableParser;
|
||||||
|
ColumnParser columnParser;
|
||||||
|
|
||||||
|
ElementDeclarationResult loadElementDeclaration(Element element) {
|
||||||
|
final result = _astForLibs.putIfAbsent(element.library.name, () {
|
||||||
|
// ignore: deprecated_member_use
|
||||||
|
return ParsedLibraryResultImpl.tmp(element.library);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result.getElementDeclaration(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String generate(LibraryReader library, BuildStep buildStep) {
|
||||||
|
final testUsers = library.findType("Users");
|
||||||
|
|
||||||
|
if (testUsers == null) return "";
|
||||||
|
|
||||||
|
TableParser(this).parse(testUsers);
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import 'package:analyzer/dart/element/type.dart';
|
||||||
|
|
||||||
|
bool isFromSally(DartType type) {
|
||||||
|
return type.element.library.location.components.first.contains("sally");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isColumn(DartType type) {
|
||||||
|
return isFromSally(type) && type.name.contains("Column");
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
dart:
|
||||||
|
- stable
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- analyze:
|
||||||
|
- dartanalyzer
|
||||||
|
- dartfmt
|
||||||
|
- unit_test:
|
||||||
|
- test
|
|
@ -0,0 +1,24 @@
|
||||||
|
name: sally_generator
|
||||||
|
description: A starting point for Dart libraries or applications.
|
||||||
|
# version: 1.0.0
|
||||||
|
# homepage: https://www.example.com
|
||||||
|
# author: Simon Binder <email@example.com>
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.1.0 <3.0.0'
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
analyzer: '< 0.35.0'
|
||||||
|
recase:
|
||||||
|
built_value:
|
||||||
|
source_gen:
|
||||||
|
sally:
|
||||||
|
path:
|
||||||
|
../sally
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
test: ^1.0.0
|
||||||
|
built_value_generator:
|
||||||
|
build_runner:
|
||||||
|
build_config:
|
||||||
|
build_test: '>=0.10.0 <0.11.0'
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/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>
|
|
@ -0,0 +1,103 @@
|
||||||
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
|
import 'package:sally_generator/src/model/specified_column.dart';
|
||||||
|
import 'package:sally_generator/src/parser/column_parser.dart';
|
||||||
|
import 'package:sally_generator/src/parser/table_parser.dart';
|
||||||
|
import 'package:sally_generator/src/sally_generator.dart';
|
||||||
|
import 'package:test_api/test_api.dart';
|
||||||
|
import 'package:build_test/build_test.dart';
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
LibraryElement testLib;
|
||||||
|
SallyGenerator generator;
|
||||||
|
|
||||||
|
setUpAll(() async {
|
||||||
|
testLib = await resolveSource(r'''
|
||||||
|
library test_parser;
|
||||||
|
|
||||||
|
import 'package:sally/sally.dart';
|
||||||
|
|
||||||
|
class TableWithCustomName extends Table {
|
||||||
|
@override
|
||||||
|
String get tableName => "my-fancy-table"
|
||||||
|
}
|
||||||
|
|
||||||
|
class Users extends Table {
|
||||||
|
IntColumn get id => integer().autoIncrement()();
|
||||||
|
TextColumn get name => text().named("user_name").withLength(min: 6, max: 32)();
|
||||||
|
TextColumn get onlyMax => text().withLength(max: 100)();
|
||||||
|
}
|
||||||
|
|
||||||
|
class WrongName extends Table {
|
||||||
|
|
||||||
|
String constructTableName() {
|
||||||
|
return "my-table-name";
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get tableName => constructTableName();"
|
||||||
|
}
|
||||||
|
''', (r) => r.findLibraryByName("test_parser"));
|
||||||
|
});
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
generator = SallyGenerator();
|
||||||
|
generator.columnParser = ColumnParser(generator);
|
||||||
|
});
|
||||||
|
|
||||||
|
group("SQL table name", () {
|
||||||
|
test("should parse correctly when valid", () {
|
||||||
|
expect(
|
||||||
|
TableParser(generator)
|
||||||
|
.parse(testLib.getType("TableWithCustomName"))
|
||||||
|
.sqlName,
|
||||||
|
equals("my-fancy-table"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should use class name if table name is not specified", () {
|
||||||
|
expect(TableParser(generator).parse(testLib.getType("Users")).sqlName,
|
||||||
|
equals("users"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should not parse for complex methods", () async {
|
||||||
|
TableParser(generator).parse(testLib.getType("WrongName"));
|
||||||
|
|
||||||
|
expect(generator.errors.errors, isNotEmpty);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group("Columns", () {
|
||||||
|
test("should use field name if no name has been set explicitely", () {
|
||||||
|
final table = TableParser(generator).parse(testLib.getType("Users"));
|
||||||
|
final idColumn =
|
||||||
|
table.columns.singleWhere((col) => col.name.name == "id");
|
||||||
|
|
||||||
|
expect(idColumn.name, equals(ColumnName.implicitly("id")));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should use explicit name, if it exists", () {
|
||||||
|
final table = TableParser(generator).parse(testLib.getType("Users"));
|
||||||
|
final idColumn =
|
||||||
|
table.columns.singleWhere((col) => col.name.name == "user_name");
|
||||||
|
|
||||||
|
expect(idColumn.name, equals(ColumnName.explicitly("user_name")));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should parse min and max length for text columns", () {
|
||||||
|
final table = TableParser(generator).parse(testLib.getType("Users"));
|
||||||
|
final idColumn =
|
||||||
|
table.columns.singleWhere((col) => col.name.name == "user_name");
|
||||||
|
|
||||||
|
expect(idColumn.features,
|
||||||
|
contains(LimitingTextLength.withLength(min: 6, max: 32)));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should only parse max length when relevant", () {
|
||||||
|
final table = TableParser(generator).parse(testLib.getType("Users"));
|
||||||
|
final idColumn =
|
||||||
|
table.columns.singleWhere((col) => col.name.name == "onlyMax");
|
||||||
|
|
||||||
|
expect(
|
||||||
|
idColumn.features, contains(LimitingTextLength.withLength(max: 100)));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Created with package:mono_repo v1.2.1
|
||||||
|
|
||||||
|
if [ -z "$PKG" ]; then
|
||||||
|
echo -e '\033[31mPKG environment variable must be set!\033[0m'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$#" == "0" ]; then
|
||||||
|
echo -e '\033[31mAt least one task argument must be provided!\033[0m'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
pushd $PKG
|
||||||
|
pub upgrade || exit $?
|
||||||
|
|
||||||
|
EXIT_CODE=0
|
||||||
|
|
||||||
|
while (( "$#" )); do
|
||||||
|
TASK=$1
|
||||||
|
case $TASK in
|
||||||
|
dartanalyzer) echo
|
||||||
|
echo -e '\033[1mTASK: dartanalyzer\033[22m'
|
||||||
|
echo -e 'dartanalyzer .'
|
||||||
|
dartanalyzer . || EXIT_CODE=$?
|
||||||
|
;;
|
||||||
|
dartfmt) echo
|
||||||
|
echo -e '\033[1mTASK: dartfmt\033[22m'
|
||||||
|
echo -e 'dartfmt -n --set-exit-if-changed .'
|
||||||
|
dartfmt -n --set-exit-if-changed . || EXIT_CODE=$?
|
||||||
|
;;
|
||||||
|
test) echo
|
||||||
|
echo -e '\033[1mTASK: test\033[22m'
|
||||||
|
echo -e 'pub run test'
|
||||||
|
pub run test || EXIT_CODE=$?
|
||||||
|
;;
|
||||||
|
*) echo -e "\033[31mNot expecting TASK '${TASK}'. Error!\033[0m"
|
||||||
|
EXIT_CODE=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
exit $EXIT_CODE
|
Loading…
Reference in New Issue