@deterministic-code/datasources 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ArrayReader.d.ts +12 -0
- package/dist/BatchCommandIBulkWriteStrategy.d.ts +33 -0
- package/dist/BuiltRepository.d.ts +16 -0
- package/dist/BulkCRUDRepository.d.ts +17 -0
- package/dist/BulkCommand.d.ts +5 -0
- package/dist/BulkWriteEnrichment.d.ts +4 -0
- package/dist/CRUDRepository.d.ts +40 -0
- package/dist/CRUDRepositoryBuilder.d.ts +19 -0
- package/dist/CRUDRepositoryOptions.d.ts +7 -0
- package/dist/CRUDRepositoryStatements.d.ts +17 -0
- package/dist/CascadeDeleteEnrichmentStrategy.d.ts +7 -0
- package/dist/CascadeDeleteUpdateEnrichmentStrategy.d.ts +8 -0
- package/dist/CommandMiddlewareHost.d.ts +22 -0
- package/dist/ConsoleCommandMiddleware.d.ts +14 -0
- package/dist/CreateEnrichmentStrategy.d.ts +14 -0
- package/dist/Datasource.d.ts +30 -0
- package/dist/DatasourceError.d.ts +3 -0
- package/dist/DatasourceFactory.d.ts +12 -0
- package/dist/DatasourceOptions.d.ts +1 -0
- package/dist/DatasourceUrl.d.ts +12 -0
- package/dist/DatasourceUrlParser.d.ts +4 -0
- package/dist/DefaultCreateEnrichmentStrategy.d.ts +7 -0
- package/dist/DefaultReadonlyEnrichmentStrategy.d.ts +19 -0
- package/dist/DefaultUpdateEnrichmentStrategy.d.ts +7 -0
- package/dist/DefaultWriteEnrichmentStrategy.d.ts +21 -0
- package/dist/DeleteEnrichmentStrategy.d.ts +11 -0
- package/dist/DriverLoader.d.ts +5 -0
- package/dist/Enrichment.d.ts +13 -0
- package/dist/EnrichmentPropertyType.d.ts +7 -0
- package/dist/ExpectConsoleMiddleware.d.ts +15 -0
- package/dist/FirstResultReader.d.ts +19 -0
- package/dist/HashsetOptimizedReadonlyEnrichmentStrategy.d.ts +9 -0
- package/dist/IBulkWriteStrategy.d.ts +12 -0
- package/dist/ICRUDRepository.d.ts +12 -0
- package/dist/ICRUDRepositoryFactory.d.ts +7 -0
- package/dist/ICommand.d.ts +20 -0
- package/dist/ICommandMiddleware.d.ts +12 -0
- package/dist/IConnection.d.ts +12 -0
- package/dist/IDatasource.d.ts +18 -0
- package/dist/IDatasourceFactory.d.ts +5 -0
- package/dist/IDriver.d.ts +19 -0
- package/dist/IEnriched.d.ts +6 -0
- package/dist/IReader.d.ts +8 -0
- package/dist/IReadonlyEnrichmentStrategy.d.ts +7 -0
- package/dist/IReadonlyRepository.d.ts +11 -0
- package/dist/IRepository.d.ts +4 -0
- package/dist/IRepositoryFactory.d.ts +7 -0
- package/dist/IRepositoryTree.d.ts +4 -0
- package/dist/IRepositoryTreeNode.d.ts +7 -0
- package/dist/ITransaction.d.ts +8 -0
- package/dist/IUnitOfWork.d.ts +5 -0
- package/dist/IWriteEnrichmentStrategy.d.ts +7 -0
- package/dist/Information.d.ts +5 -0
- package/dist/IsolationLevel.d.ts +7 -0
- package/dist/LazyWriteEnrichmentStrategy.d.ts +4 -0
- package/dist/NestedToObjectEnrichmentStrategy.d.ts +10 -0
- package/dist/Parameter.d.ts +7 -0
- package/dist/ParameterDirection.d.ts +7 -0
- package/dist/ProviderCatalog.d.ts +7 -0
- package/dist/ProviderNotImplementedError.d.ts +4 -0
- package/dist/ProviderNotInstalledError.d.ts +4 -0
- package/dist/ReadonlyRepository.d.ts +59 -0
- package/dist/ReadonlyRepositoryBuilder.d.ts +12 -0
- package/dist/ReadonlyRepositoryMappingOptions.d.ts +14 -0
- package/dist/ReadonlyRepositoryStatements.d.ts +8 -0
- package/dist/RepositoryAccess.d.ts +11 -0
- package/dist/RepositoryFactory.d.ts +23 -0
- package/dist/RepositoryNotRegisteredError.d.ts +4 -0
- package/dist/RepositoryTree.d.ts +6 -0
- package/dist/RepositoryTreeNode.d.ts +9 -0
- package/dist/Response.d.ts +7 -0
- package/dist/Row.d.ts +2 -0
- package/dist/SingleCommandIBulkWriteStrategy.d.ts +11 -0
- package/dist/StatementMappers.d.ts +16 -0
- package/dist/StoredEnrichment.d.ts +11 -0
- package/dist/StoredProcedureBulkWriteStrategy.d.ts +27 -0
- package/dist/StreamingReader.d.ts +16 -0
- package/dist/UnitOfWorkTransaction.d.ts +12 -0
- package/dist/UpdateEnrichmentStrategy.d.ts +18 -0
- package/dist/WriteMode.d.ts +1 -0
- package/dist/builders/Field.d.ts +5 -0
- package/dist/builders/Scalar.d.ts +1 -0
- package/dist/builders/index.d.ts +2 -0
- package/dist/collectAsync.d.ts +1 -0
- package/dist/converters/Cell.d.ts +2 -0
- package/dist/converters/ChangeCasingConverter.d.ts +7 -0
- package/dist/converters/Constructable.d.ts +1 -0
- package/dist/converters/MetaDataRowTypeConverter.d.ts +14 -0
- package/dist/converters/PluralizerConverter.d.ts +4 -0
- package/dist/converters/RegexConverter.d.ts +7 -0
- package/dist/converters/ReplaceConverter.d.ts +7 -0
- package/dist/converters/RowTypeConverter.d.ts +10 -0
- package/dist/converters/ToLowerCaseConverter.d.ts +4 -0
- package/dist/converters/ToUpperCaseConverter.d.ts +4 -0
- package/dist/converters/TypeConverter.d.ts +5 -0
- package/dist/createCRUDRepositoryOptions.d.ts +7 -0
- package/dist/createReadonlyRepositoryMappingOptions.d.ts +6 -0
- package/dist/dotEnv.d.ts +5 -0
- package/dist/index.d.ts +119 -0
- package/dist/mappers/ChangeCasingMapper.d.ts +9 -0
- package/dist/mappers/DictionaryMapper.d.ts +8 -0
- package/dist/mappers/FlatToNestedMapper.d.ts +20 -0
- package/dist/mappers/IFlatToNestedMapper.d.ts +6 -0
- package/dist/mappers/IMapper.d.ts +4 -0
- package/dist/mappers/IdentityMapper.d.ts +5 -0
- package/dist/mappers/PluralizerMapper.d.ts +6 -0
- package/dist/mappers/RowTypeMapper.d.ts +6 -0
- package/dist/mappers/TransformConverterMapper.d.ts +5 -0
- package/dist/mappers/TransformMapper.d.ts +6 -0
- package/dist/mappers/TypeMap.d.ts +8 -0
- package/dist/mappers/TypeMapGroup.d.ts +5 -0
- package/dist/mocks/index.d.ts +9 -0
- package/dist/mocks/mock-command.d.ts +28 -0
- package/dist/mocks/mock-connection.d.ts +22 -0
- package/dist/mocks/mock-datasource.d.ts +24 -0
- package/dist/mocks/mock-driver.d.ts +15 -0
- package/dist/mocks/mock-reader.d.ts +14 -0
- package/dist/mocks/mock-repository.d.ts +42 -0
- package/dist/mocks/mock-select-statement.d.ts +10 -0
- package/dist/mocks/mock-transaction.d.ts +16 -0
- package/dist/mocks/mock-where.d.ts +8 -0
- package/dist/parametersToRecord.d.ts +2 -0
- package/dist/readerToAsyncIterable.d.ts +2 -0
- package/dist/splitStatements.d.ts +1 -0
- package/dist/statementParameters.d.ts +1 -0
- package/dist/statementUsesParameter.d.ts +1 -0
- package/dist/statements/Aggregate.d.ts +6 -0
- package/dist/statements/ArrayExpression.d.ts +5 -0
- package/dist/statements/BulkDeleteStatement.d.ts +11 -0
- package/dist/statements/BulkDeleteStatementTextRenderer.d.ts +4 -0
- package/dist/statements/BulkInsertStatement.d.ts +12 -0
- package/dist/statements/BulkInsertStatementTextRenderer.d.ts +4 -0
- package/dist/statements/BulkUpdateStatement.d.ts +16 -0
- package/dist/statements/BulkUpdateStatementTextRenderer.d.ts +8 -0
- package/dist/statements/CheckConstraint.d.ts +7 -0
- package/dist/statements/Cmp.d.ts +9 -0
- package/dist/statements/Column.d.ts +9 -0
- package/dist/statements/ColumnDefault.d.ts +5 -0
- package/dist/statements/Condition.d.ts +3 -0
- package/dist/statements/ConditionRenderer.d.ts +12 -0
- package/dist/statements/CreateIndexStatement.d.ts +10 -0
- package/dist/statements/CreateIndexStatementTextRenderer.d.ts +5 -0
- package/dist/statements/CreateTableStatement.d.ts +11 -0
- package/dist/statements/CreateTableStatementTextRenderer.d.ts +18 -0
- package/dist/statements/DefaultStatementTextRenderer.d.ts +5 -0
- package/dist/statements/DeleteStatement.d.ts +9 -0
- package/dist/statements/DeleteStatementTextRenderer.d.ts +7 -0
- package/dist/statements/ExecuteStoredProcedureStatement.d.ts +9 -0
- package/dist/statements/ExecuteStoredProcedureStatementTextRenderer.d.ts +4 -0
- package/dist/statements/ExpressionEvaluator.d.ts +5 -0
- package/dist/statements/ExpressionRenderer.d.ts +8 -0
- package/dist/statements/ForeignKey.d.ts +19 -0
- package/dist/statements/IBulkDeleteStatement.d.ts +3 -0
- package/dist/statements/IBulkInsertStatement.d.ts +3 -0
- package/dist/statements/IBulkUpdateStatement.d.ts +3 -0
- package/dist/statements/ICondition.d.ts +4 -0
- package/dist/statements/IConditionVisitor.d.ts +6 -0
- package/dist/statements/ICreateIndexStatement.d.ts +3 -0
- package/dist/statements/ICreateTableStatement.d.ts +3 -0
- package/dist/statements/IDeleteStatement.d.ts +5 -0
- package/dist/statements/IExecuteStoredProcedureStatement.d.ts +3 -0
- package/dist/statements/IExpression.d.ts +2 -0
- package/dist/statements/IInsertStatement.d.ts +3 -0
- package/dist/statements/IReturnStatement.d.ts +3 -0
- package/dist/statements/ISelectStatement.d.ts +5 -0
- package/dist/statements/IStatement.d.ts +4 -0
- package/dist/statements/IStatementVisitor.d.ts +26 -0
- package/dist/statements/ITableConstraint.d.ts +5 -0
- package/dist/statements/IUpdateStatement.d.ts +5 -0
- package/dist/statements/IWhere.d.ts +6 -0
- package/dist/statements/Identifier.d.ts +5 -0
- package/dist/statements/InsertStatement.d.ts +9 -0
- package/dist/statements/InsertStatementTextRenderer.d.ts +4 -0
- package/dist/statements/Join.d.ts +14 -0
- package/dist/statements/Literal.d.ts +6 -0
- package/dist/statements/Native.d.ts +5 -0
- package/dist/statements/NotNull.d.ts +4 -0
- package/dist/statements/Operator.d.ts +107 -0
- package/dist/statements/OrderBy.d.ts +10 -0
- package/dist/statements/PrimaryKey.d.ts +7 -0
- package/dist/statements/ReturnStatement.d.ts +9 -0
- package/dist/statements/ReturnStatementTextRenderer.d.ts +4 -0
- package/dist/statements/SelectInsertedIdStatement.d.ts +8 -0
- package/dist/statements/SelectInsertedIdStatementTextRenderer.d.ts +4 -0
- package/dist/statements/SelectStatement.d.ts +20 -0
- package/dist/statements/SelectStatementOptions.d.ts +15 -0
- package/dist/statements/SelectStatementTextRenderer.d.ts +19 -0
- package/dist/statements/StatementEvaluator.d.ts +4 -0
- package/dist/statements/StatementParser.d.ts +4 -0
- package/dist/statements/StatementRenderer.d.ts +42 -0
- package/dist/statements/StatementTextRenderer.d.ts +14 -0
- package/dist/statements/Subquery.d.ts +6 -0
- package/dist/statements/UniqueConstraint.d.ts +7 -0
- package/dist/statements/UpdateStatement.d.ts +14 -0
- package/dist/statements/UpdateStatementTextRenderer.d.ts +14 -0
- package/dist/statements/Where.d.ts +16 -0
- package/dist/statements/WhereText.d.ts +8 -0
- package/dist/statements/index.d.ts +75 -0
- package/dist/stubs/StubCommand.d.ts +15 -0
- package/dist/stubs/StubConnection.d.ts +13 -0
- package/dist/stubs/StubDatasource.d.ts +20 -0
- package/dist/stubs/StubReader.d.ts +11 -0
- package/dist/stubs/StubRepository.d.ts +22 -0
- package/dist/stubs/StubTransaction.d.ts +10 -0
- package/dist/stubs/createStubDatasource.d.ts +2 -0
- package/dist/stubs/index.d.ts +7 -0
- package/dist/stubs/notImplemented.d.ts +1 -0
- package/package.json +24 -4
- package/src/ArrayReader.test.ts +23 -0
- package/src/ArrayReader.ts +32 -0
- package/src/BatchCommandIBulkWriteStrategy.ts +228 -0
- package/src/BuiltRepository.ts +17 -0
- package/src/BulkCRUDRepository.test.ts +183 -0
- package/src/BulkCRUDRepository.ts +84 -0
- package/src/BulkCommand.ts +6 -0
- package/src/BulkWriteEnrichment.ts +19 -0
- package/src/BulkWriteStrategy.test.ts +293 -0
- package/src/CRUDRepository.test.ts +420 -0
- package/src/CRUDRepository.ts +264 -0
- package/src/CRUDRepositoryBuilder.ts +53 -0
- package/src/CRUDRepositoryOptions.test.ts +76 -0
- package/src/CRUDRepositoryOptions.ts +8 -0
- package/src/CRUDRepositoryStatements.ts +43 -0
- package/src/CascadeDeleteEnrichmentStrategy.ts +51 -0
- package/src/CascadeDeleteUpdateEnrichmentStrategy.ts +28 -0
- package/src/Command.test.ts +105 -0
- package/src/CommandMiddlewareHost.test.ts +98 -0
- package/src/CommandMiddlewareHost.ts +113 -0
- package/src/Connection.test.ts +34 -0
- package/src/ConsoleCommandMiddleware.test.ts +149 -0
- package/src/ConsoleCommandMiddleware.ts +64 -0
- package/src/CreateEnrichmentStrategy.ts +82 -0
- package/src/Datasource.test.ts +63 -0
- package/src/Datasource.ts +152 -0
- package/src/DatasourceError.test.ts +10 -0
- package/src/DatasourceError.ts +6 -0
- package/src/DatasourceFactory.test.ts +159 -0
- package/src/DatasourceFactory.ts +86 -0
- package/src/DatasourceOptions.ts +1 -0
- package/src/DatasourceUrl.ts +37 -0
- package/src/DatasourceUrlParser.test.ts +173 -0
- package/src/DatasourceUrlParser.ts +188 -0
- package/src/DefaultCreateEnrichmentStrategy.ts +21 -0
- package/src/DefaultReadonlyEnrichmentStrategy.ts +164 -0
- package/src/DefaultUpdateEnrichmentStrategy.ts +40 -0
- package/src/DefaultWriteEnrichmentStrategy.ts +151 -0
- package/src/DeleteEnrichmentStrategy.ts +56 -0
- package/src/DriverLoader.ts +97 -0
- package/src/Enrichment.ts +15 -0
- package/src/EnrichmentPropertyType.ts +9 -0
- package/src/ExpectConsoleMiddleware.test.ts +79 -0
- package/src/ExpectConsoleMiddleware.ts +47 -0
- package/src/FirstResultReader.test.ts +43 -0
- package/src/FirstResultReader.ts +49 -0
- package/src/HashsetOptimizedReadonlyEnrichmentStrategy.ts +80 -0
- package/src/IBulkWriteStrategy.ts +13 -0
- package/src/ICRUDRepository.ts +13 -0
- package/src/ICRUDRepositoryFactory.ts +8 -0
- package/src/ICommand.ts +45 -0
- package/src/ICommandMiddleware.ts +20 -0
- package/src/IConnection.ts +13 -0
- package/src/IDatasource.ts +27 -0
- package/src/IDatasourceFactory.ts +6 -0
- package/src/IDriver.ts +24 -0
- package/src/IEnriched.ts +11 -0
- package/src/IReader.ts +8 -0
- package/src/IReadonlyEnrichmentStrategy.ts +19 -0
- package/src/IReadonlyRepository.ts +21 -0
- package/src/IRepository.ts +5 -0
- package/src/IRepositoryFactory.ts +8 -0
- package/src/IRepositoryTree.ts +5 -0
- package/src/IRepositoryTreeNode.ts +8 -0
- package/src/ITransaction.ts +9 -0
- package/src/IUnitOfWork.ts +5 -0
- package/src/IWriteEnrichmentStrategy.ts +8 -0
- package/src/Information.ts +5 -0
- package/src/IsolationLevel.test.ts +13 -0
- package/src/IsolationLevel.ts +8 -0
- package/src/LazyWriteEnrichmentStrategy.ts +5 -0
- package/src/NestedToObjectEnrichmentStrategy.ts +33 -0
- package/src/Parameter.ts +8 -0
- package/src/ParameterDirection.ts +9 -0
- package/src/ProviderCatalog.test.ts +110 -0
- package/src/ProviderCatalog.ts +21 -0
- package/src/ProviderNotImplementedError.test.ts +11 -0
- package/src/ProviderNotImplementedError.ts +9 -0
- package/src/ProviderNotInstalledError.test.ts +11 -0
- package/src/ProviderNotInstalledError.ts +9 -0
- package/src/ReadonlyRepository.test.ts +406 -0
- package/src/ReadonlyRepository.ts +276 -0
- package/src/ReadonlyRepositoryBuilder.ts +53 -0
- package/src/ReadonlyRepositoryMappingOptions.ts +15 -0
- package/src/ReadonlyRepositoryStatements.ts +13 -0
- package/src/RepositoryAccess.ts +14 -0
- package/src/RepositoryFactory.test.ts +94 -0
- package/src/RepositoryFactory.ts +115 -0
- package/src/RepositoryNotRegisteredError.ts +9 -0
- package/src/RepositoryTree.ts +6 -0
- package/src/RepositoryTreeNode.ts +11 -0
- package/src/Response.ts +15 -0
- package/src/Row.ts +3 -0
- package/src/SingleCommandIBulkWriteStrategy.ts +35 -0
- package/src/StatementMappers.test.ts +221 -0
- package/src/StatementMappers.ts +110 -0
- package/src/StoredEnrichment.ts +25 -0
- package/src/StoredProcedureBulkWriteStrategy.ts +164 -0
- package/src/StreamingReader.test.ts +126 -0
- package/src/StreamingReader.ts +64 -0
- package/src/Transaction.test.ts +37 -0
- package/src/UnitOfWorkTransaction.test.ts +43 -0
- package/src/UnitOfWorkTransaction.ts +50 -0
- package/src/UpdateEnrichmentStrategy.ts +97 -0
- package/src/UserViewCRUDRepository.test.ts +323 -0
- package/src/WriteMode.ts +1 -0
- package/src/builders/Field.ts +6 -0
- package/src/builders/Scalar.ts +1 -0
- package/src/builders/builders.test.ts +404 -0
- package/src/builders/index.ts +2 -0
- package/src/collectAsync.ts +7 -0
- package/src/converters/Cell.ts +10 -0
- package/src/converters/ChangeCasingConverter.test.ts +34 -0
- package/src/converters/ChangeCasingConverter.ts +59 -0
- package/src/converters/Constructable.ts +1 -0
- package/src/converters/MetaDataRowTypeConverter.ts +80 -0
- package/src/converters/PluralizerConverter.test.ts +43 -0
- package/src/converters/PluralizerConverter.ts +67 -0
- package/src/converters/RegexConverter.test.ts +11 -0
- package/src/converters/RegexConverter.ts +14 -0
- package/src/converters/ReplaceConverter.test.ts +9 -0
- package/src/converters/ReplaceConverter.ts +6 -0
- package/src/converters/RowTypeConverter.test.ts +79 -0
- package/src/converters/RowTypeConverter.ts +33 -0
- package/src/converters/ToLowerCaseConverter.test.ts +9 -0
- package/src/converters/ToLowerCaseConverter.ts +4 -0
- package/src/converters/ToUpperCaseConverter.test.ts +9 -0
- package/src/converters/ToUpperCaseConverter.ts +4 -0
- package/src/converters/TypeConverter.ts +6 -0
- package/src/createCRUDRepositoryOptions.ts +21 -0
- package/src/createReadonlyRepositoryMappingOptions.ts +26 -0
- package/src/dotEnv.test.ts +21 -0
- package/src/dotEnv.ts +16 -0
- package/src/edgeCases.test.ts +485 -0
- package/src/index.ts +222 -0
- package/src/mappers/ChangeCasingMapper.test.ts +32 -0
- package/src/mappers/ChangeCasingMapper.ts +15 -0
- package/src/mappers/DictionaryMapper.test.ts +69 -0
- package/src/mappers/DictionaryMapper.ts +16 -0
- package/src/mappers/FlatToNestedMapper.test.ts +269 -0
- package/src/mappers/FlatToNestedMapper.ts +127 -0
- package/src/mappers/IFlatToNestedMapper.ts +7 -0
- package/src/mappers/IMapper.ts +4 -0
- package/src/mappers/IdentityMapper.test.ts +12 -0
- package/src/mappers/IdentityMapper.ts +6 -0
- package/src/mappers/PluralizerMapper.test.ts +40 -0
- package/src/mappers/PluralizerMapper.ts +9 -0
- package/src/mappers/RowTypeMapper.test.ts +12 -0
- package/src/mappers/RowTypeMapper.ts +13 -0
- package/src/mappers/TransformConverterMapper.test.ts +181 -0
- package/src/mappers/TransformConverterMapper.ts +11 -0
- package/src/mappers/TransformMapper.ts +8 -0
- package/src/mappers/TypeMap.ts +10 -0
- package/src/mappers/TypeMapGroup.ts +6 -0
- package/src/mappers/transformMapper.test.ts +66 -0
- package/src/mocks/MockCommand.test.ts +75 -0
- package/src/mocks/MockConnection.test.ts +34 -0
- package/src/mocks/MockDatasource.test.ts +40 -0
- package/src/mocks/MockReader.test.ts +17 -0
- package/src/mocks/MockRepository.test.ts +32 -0
- package/src/mocks/MockSelectStatement.test.ts +11 -0
- package/src/mocks/MockTransaction.test.ts +17 -0
- package/src/mocks/MockWhere.test.ts +11 -0
- package/src/mocks/index.ts +9 -0
- package/src/mocks/mock-command.ts +66 -0
- package/src/mocks/mock-connection.ts +57 -0
- package/src/mocks/mock-datasource.ts +65 -0
- package/src/mocks/mock-driver.ts +27 -0
- package/src/mocks/mock-reader.ts +38 -0
- package/src/mocks/mock-repository.ts +91 -0
- package/src/mocks/mock-select-statement.ts +17 -0
- package/src/mocks/mock-transaction.ts +31 -0
- package/src/mocks/mock-where.ts +13 -0
- package/src/parametersToRecord.test.ts +19 -0
- package/src/parametersToRecord.ts +11 -0
- package/src/public-surface.test.ts +23 -0
- package/src/readWithWhereClauseAndCustomFlatToNestedObjectMappingOptions.test.ts +126 -0
- package/src/readerToAsyncIterable.test.ts +39 -0
- package/src/readerToAsyncIterable.ts +11 -0
- package/src/repository.test.ts +410 -0
- package/src/repository.type.test.ts +29 -0
- package/src/splitStatements.ts +99 -0
- package/src/statementParameters.ts +22 -0
- package/src/statementUsesParameter.ts +4 -0
- package/src/statements/Aggregate.ts +9 -0
- package/src/statements/ArrayExpression.ts +5 -0
- package/src/statements/BulkDeleteStatement.ts +18 -0
- package/src/statements/BulkDeleteStatementTextRenderer.ts +16 -0
- package/src/statements/BulkInsertStatement.ts +37 -0
- package/src/statements/BulkInsertStatementTextRenderer.ts +10 -0
- package/src/statements/BulkUpdateStatement.ts +24 -0
- package/src/statements/BulkUpdateStatementTextRenderer.ts +29 -0
- package/src/statements/CheckConstraint.ts +9 -0
- package/src/statements/Cmp.ts +12 -0
- package/src/statements/Column.ts +10 -0
- package/src/statements/ColumnDefault.ts +6 -0
- package/src/statements/Condition.ts +3 -0
- package/src/statements/ConditionRenderer.ts +17 -0
- package/src/statements/CreateIndexStatement.ts +18 -0
- package/src/statements/CreateIndexStatementTextRenderer.ts +11 -0
- package/src/statements/CreateTableStatement.ts +18 -0
- package/src/statements/CreateTableStatementTextRenderer.ts +92 -0
- package/src/statements/DefaultStatementTextRenderer.ts +9 -0
- package/src/statements/DeleteStatement.ts +15 -0
- package/src/statements/DeleteStatementTextRenderer.ts +12 -0
- package/src/statements/ExecuteStoredProcedureStatement.ts +15 -0
- package/src/statements/ExecuteStoredProcedureStatementTextRenderer.ts +15 -0
- package/src/statements/ExpressionEvaluator.ts +166 -0
- package/src/statements/ExpressionRenderer.ts +161 -0
- package/src/statements/ForeignKey.ts +23 -0
- package/src/statements/IBulkDeleteStatement.ts +3 -0
- package/src/statements/IBulkInsertStatement.ts +3 -0
- package/src/statements/IBulkUpdateStatement.ts +3 -0
- package/src/statements/ICondition.ts +5 -0
- package/src/statements/IConditionVisitor.ts +7 -0
- package/src/statements/ICreateIndexStatement.ts +3 -0
- package/src/statements/ICreateTableStatement.ts +3 -0
- package/src/statements/IDeleteStatement.ts +6 -0
- package/src/statements/IExecuteStoredProcedureStatement.ts +3 -0
- package/src/statements/IExpression.ts +1 -0
- package/src/statements/IInsertStatement.ts +3 -0
- package/src/statements/IReturnStatement.ts +3 -0
- package/src/statements/ISelectStatement.ts +6 -0
- package/src/statements/IStatement.ts +5 -0
- package/src/statements/IStatementVisitor.ts +27 -0
- package/src/statements/ITableConstraint.ts +6 -0
- package/src/statements/IUpdateStatement.ts +6 -0
- package/src/statements/IWhere.ts +7 -0
- package/src/statements/Identifier.ts +5 -0
- package/src/statements/InsertStatement.ts +15 -0
- package/src/statements/InsertStatementTextRenderer.ts +7 -0
- package/src/statements/Join.ts +26 -0
- package/src/statements/Literal.ts +6 -0
- package/src/statements/Native.ts +5 -0
- package/src/statements/NotNull.ts +3 -0
- package/src/statements/Operator.ts +234 -0
- package/src/statements/OrderBy.ts +19 -0
- package/src/statements/PrimaryKey.ts +9 -0
- package/src/statements/ReturnStatement.ts +15 -0
- package/src/statements/ReturnStatementTextRenderer.ts +15 -0
- package/src/statements/SelectInsertedIdStatement.test.ts +11 -0
- package/src/statements/SelectInsertedIdStatement.ts +11 -0
- package/src/statements/SelectInsertedIdStatementTextRenderer.ts +7 -0
- package/src/statements/SelectStatement.ts +34 -0
- package/src/statements/SelectStatementOptions.ts +16 -0
- package/src/statements/SelectStatementTextRenderer.ts +71 -0
- package/src/statements/StatementCompile.test.ts +231 -0
- package/src/statements/StatementEvaluator.ts +5 -0
- package/src/statements/StatementParser.test.ts +304 -0
- package/src/statements/StatementParser.ts +461 -0
- package/src/statements/StatementRenderer.ts +120 -0
- package/src/statements/StatementTextRenderer.ts +60 -0
- package/src/statements/Subquery.ts +6 -0
- package/src/statements/UniqueConstraint.ts +9 -0
- package/src/statements/UpdateStatement.ts +34 -0
- package/src/statements/UpdateStatementTextRenderer.ts +63 -0
- package/src/statements/Where.ts +250 -0
- package/src/statements/WhereText.ts +10 -0
- package/src/statements/index.ts +75 -0
- package/src/stubs/StubCommand.ts +30 -0
- package/src/stubs/StubConnection.ts +21 -0
- package/src/stubs/StubDatasource.test.ts +99 -0
- package/src/stubs/StubDatasource.ts +60 -0
- package/src/stubs/StubReader.ts +25 -0
- package/src/stubs/StubRepository.ts +42 -0
- package/src/stubs/StubTransaction.ts +17 -0
- package/src/stubs/createStubDatasource.ts +4 -0
- package/src/stubs/index.ts +7 -0
- package/src/stubs/notImplemented.ts +5 -0
- package/src/tests/contact/Address.ts +14 -0
- package/src/tests/contact/AddressType.ts +6 -0
- package/src/tests/contact/Base.ts +7 -0
- package/src/tests/contact/Contact.ts +12 -0
- package/src/tests/contact/ContactBase.ts +8 -0
- package/src/tests/contact/ContactChangeLog.ts +8 -0
- package/src/tests/contact/ContactGroup.ts +6 -0
- package/src/tests/contact/ContactGroupBase.ts +6 -0
- package/src/tests/contact/ContactGroupMember.ts +6 -0
- package/src/tests/contact/ContactSource.ts +6 -0
- package/src/tests/contact/ContactType.ts +6 -0
- package/src/tests/contact/ContactsService.test.ts +118 -0
- package/src/tests/contact/ContactsService.ts +32 -0
- package/src/tests/contact/ImportContactRequest.ts +4 -0
- package/src/tests/contact/ImportContactResult.ts +5 -0
- package/src/tests/contact/LegacyContact.ts +7 -0
- package/src/tests/contact/LegacyMigrationResult.ts +5 -0
- package/src/tests/contact/Phone.ts +9 -0
- package/src/tests/contact/PhoneType.ts +6 -0
- package/src/tests/contact/asContactsView.ts +63 -0
- package/src/tests/contact/contactColumns.ts +40 -0
- package/src/tests/contact/contactLookupIds.ts +32 -0
- package/src/tests/contact/contactLookups.ts +6 -0
- package/src/tests/contact/contactsParity.ts +63 -0
- package/src/tests/contact/contactsServiceOf.ts +38 -0
- package/src/tests/contact/contactsView.ts +31 -0
- package/src/tests/contact/expectContactsView.ts +23 -0
- package/src/tests/contact/extraContact.ts +61 -0
- package/src/tests/contact/logMapped.ts +5 -0
- package/src/tests/contact/seedContacts.ts +31 -0
- package/README.md +0 -3
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import type { Cell } from "../converters/Cell.ts";
|
|
2
|
+
import { ArrayExpression } from "./ArrayExpression.ts";
|
|
3
|
+
import { Condition } from "./Condition.ts";
|
|
4
|
+
import { Identifier } from "./Identifier.ts";
|
|
5
|
+
import type { IExpression } from "./IExpression.ts";
|
|
6
|
+
import { Literal } from "./Literal.ts";
|
|
7
|
+
|
|
8
|
+
const pair = (
|
|
9
|
+
left: string | IExpression,
|
|
10
|
+
right: IExpression | Cell,
|
|
11
|
+
): [IExpression, IExpression] =>
|
|
12
|
+
typeof left === "string"
|
|
13
|
+
? [new Identifier(left), new Literal(right as Cell)]
|
|
14
|
+
: [left, right as IExpression];
|
|
15
|
+
|
|
16
|
+
export abstract class Operator extends Condition {}
|
|
17
|
+
|
|
18
|
+
export namespace Operator {
|
|
19
|
+
export class Equals extends Operator {
|
|
20
|
+
readonly left: IExpression;
|
|
21
|
+
readonly right: IExpression;
|
|
22
|
+
constructor(field: string, value: Cell);
|
|
23
|
+
constructor(left: IExpression, right: IExpression);
|
|
24
|
+
constructor(left: string | IExpression, right: IExpression | Cell) {
|
|
25
|
+
super();
|
|
26
|
+
[this.left, this.right] = pair(left, right);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class NotEquals extends Operator {
|
|
31
|
+
readonly left: IExpression;
|
|
32
|
+
readonly right: IExpression;
|
|
33
|
+
constructor(field: string, value: Cell);
|
|
34
|
+
constructor(left: IExpression, right: IExpression);
|
|
35
|
+
constructor(left: string | IExpression, right: IExpression | Cell) {
|
|
36
|
+
super();
|
|
37
|
+
[this.left, this.right] = pair(left, right);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class GreaterThan extends Operator {
|
|
42
|
+
readonly left: IExpression;
|
|
43
|
+
readonly right: IExpression;
|
|
44
|
+
constructor(field: string, value: Cell);
|
|
45
|
+
constructor(left: IExpression, right: IExpression);
|
|
46
|
+
constructor(left: string | IExpression, right: IExpression | Cell) {
|
|
47
|
+
super();
|
|
48
|
+
[this.left, this.right] = pair(left, right);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export class LessThan extends Operator {
|
|
53
|
+
readonly left: IExpression;
|
|
54
|
+
readonly right: IExpression;
|
|
55
|
+
constructor(field: string, value: Cell);
|
|
56
|
+
constructor(left: IExpression, right: IExpression);
|
|
57
|
+
constructor(left: string | IExpression, right: IExpression | Cell) {
|
|
58
|
+
super();
|
|
59
|
+
[this.left, this.right] = pair(left, right);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export class GreaterThanOrEqual extends Operator {
|
|
64
|
+
readonly left: IExpression;
|
|
65
|
+
readonly right: IExpression;
|
|
66
|
+
constructor(field: string, value: Cell);
|
|
67
|
+
constructor(left: IExpression, right: IExpression);
|
|
68
|
+
constructor(left: string | IExpression, right: IExpression | Cell) {
|
|
69
|
+
super();
|
|
70
|
+
[this.left, this.right] = pair(left, right);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export class LessThanOrEqual extends Operator {
|
|
75
|
+
readonly left: IExpression;
|
|
76
|
+
readonly right: IExpression;
|
|
77
|
+
constructor(field: string, value: Cell);
|
|
78
|
+
constructor(left: IExpression, right: IExpression);
|
|
79
|
+
constructor(left: string | IExpression, right: IExpression | Cell) {
|
|
80
|
+
super();
|
|
81
|
+
[this.left, this.right] = pair(left, right);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export class And extends Operator {
|
|
86
|
+
constructor(
|
|
87
|
+
readonly left: IExpression,
|
|
88
|
+
readonly right: IExpression,
|
|
89
|
+
) {
|
|
90
|
+
super();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export class Or extends Operator {
|
|
95
|
+
constructor(
|
|
96
|
+
readonly left: IExpression,
|
|
97
|
+
readonly right: IExpression,
|
|
98
|
+
) {
|
|
99
|
+
super();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export class In extends Operator {
|
|
104
|
+
readonly left: IExpression;
|
|
105
|
+
readonly right: IExpression;
|
|
106
|
+
constructor(field: string, values: Cell[]);
|
|
107
|
+
constructor(left: IExpression, right: IExpression);
|
|
108
|
+
constructor(left: string | IExpression, right: Cell[] | IExpression) {
|
|
109
|
+
super();
|
|
110
|
+
if (typeof left === "string") {
|
|
111
|
+
this.left = new Identifier(left);
|
|
112
|
+
this.right = new ArrayExpression(
|
|
113
|
+
(right as Cell[]).map((value) => new Literal(value)),
|
|
114
|
+
);
|
|
115
|
+
} else {
|
|
116
|
+
this.left = left;
|
|
117
|
+
this.right = right as IExpression;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* v8 ignore next 6 */
|
|
123
|
+
export class Not extends Operator {
|
|
124
|
+
readonly argument: IExpression;
|
|
125
|
+
constructor(argument: IExpression) {
|
|
126
|
+
super();
|
|
127
|
+
this.argument = argument;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export class IsNull extends Operator {
|
|
132
|
+
readonly argument: IExpression;
|
|
133
|
+
constructor(argument: IExpression) {
|
|
134
|
+
super();
|
|
135
|
+
this.argument = argument;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export class IsNotNull extends Operator {
|
|
140
|
+
readonly argument: IExpression;
|
|
141
|
+
constructor(argument: IExpression) {
|
|
142
|
+
super();
|
|
143
|
+
this.argument = argument;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export class Like extends Operator {
|
|
148
|
+
readonly left: IExpression;
|
|
149
|
+
readonly right: IExpression;
|
|
150
|
+
constructor(field: string, value: Cell);
|
|
151
|
+
constructor(left: IExpression, right: IExpression);
|
|
152
|
+
constructor(left: string | IExpression, right: IExpression | Cell) {
|
|
153
|
+
super();
|
|
154
|
+
[this.left, this.right] = pair(left, right);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export class NotLike extends Operator {
|
|
159
|
+
readonly left: IExpression;
|
|
160
|
+
readonly right: IExpression;
|
|
161
|
+
constructor(field: string, value: Cell);
|
|
162
|
+
constructor(left: IExpression, right: IExpression);
|
|
163
|
+
constructor(left: string | IExpression, right: IExpression | Cell) {
|
|
164
|
+
super();
|
|
165
|
+
[this.left, this.right] = pair(left, right);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export class Between extends Operator {
|
|
170
|
+
readonly value: IExpression;
|
|
171
|
+
readonly low: IExpression;
|
|
172
|
+
readonly high: IExpression;
|
|
173
|
+
constructor(field: string, low: Cell, high: Cell);
|
|
174
|
+
constructor(value: IExpression, low: IExpression, high: IExpression);
|
|
175
|
+
constructor(value: string | IExpression, low: IExpression | Cell, high: IExpression | Cell) {
|
|
176
|
+
super();
|
|
177
|
+
if (typeof value === "string") {
|
|
178
|
+
this.value = new Identifier(value);
|
|
179
|
+
this.low = new Literal(low as Cell);
|
|
180
|
+
this.high = new Literal(high as Cell);
|
|
181
|
+
} else {
|
|
182
|
+
this.value = value;
|
|
183
|
+
this.low = low as IExpression;
|
|
184
|
+
this.high = high as IExpression;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export class NotBetween extends Operator {
|
|
190
|
+
readonly value: IExpression;
|
|
191
|
+
readonly low: IExpression;
|
|
192
|
+
readonly high: IExpression;
|
|
193
|
+
constructor(field: string, low: Cell, high: Cell);
|
|
194
|
+
constructor(value: IExpression, low: IExpression, high: IExpression);
|
|
195
|
+
constructor(value: string | IExpression, low: IExpression | Cell, high: IExpression | Cell) {
|
|
196
|
+
super();
|
|
197
|
+
if (typeof value === "string") {
|
|
198
|
+
this.value = new Identifier(value);
|
|
199
|
+
this.low = new Literal(low as Cell);
|
|
200
|
+
this.high = new Literal(high as Cell);
|
|
201
|
+
} else {
|
|
202
|
+
this.value = value;
|
|
203
|
+
this.low = low as IExpression;
|
|
204
|
+
this.high = high as IExpression;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export class NotIn extends Operator {
|
|
210
|
+
readonly left: IExpression;
|
|
211
|
+
readonly right: IExpression;
|
|
212
|
+
constructor(field: string, values: Cell[]);
|
|
213
|
+
constructor(left: IExpression, right: IExpression);
|
|
214
|
+
constructor(left: string | IExpression, right: Cell[] | IExpression) {
|
|
215
|
+
super();
|
|
216
|
+
if (typeof left === "string") {
|
|
217
|
+
this.left = new Identifier(left);
|
|
218
|
+
this.right = new ArrayExpression((right as Cell[]).map((value) => new Literal(value)));
|
|
219
|
+
} else {
|
|
220
|
+
this.left = left;
|
|
221
|
+
this.right = right as IExpression;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* v8 ignore next */
|
|
227
|
+
export class Exists extends Operator {
|
|
228
|
+
readonly argument: IExpression;
|
|
229
|
+
constructor(argument: IExpression) {
|
|
230
|
+
super();
|
|
231
|
+
this.argument = argument;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type SortDirection = "asc" | "desc";
|
|
2
|
+
|
|
3
|
+
export type OrderBy = {
|
|
4
|
+
column: string;
|
|
5
|
+
direction: SortDirection;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const directionSql: Record<SortDirection, string> = {
|
|
9
|
+
asc: "ASC",
|
|
10
|
+
desc: "DESC",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const OrderBy = {
|
|
14
|
+
asc: (column: string): OrderBy => ({ column, direction: "asc" }),
|
|
15
|
+
desc: (column: string): OrderBy => ({ column, direction: "desc" }),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const orderText = (order: OrderBy): string =>
|
|
19
|
+
`${order.column} ${directionSql[order.direction]}`;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Parameter } from "../Parameter.ts";
|
|
2
|
+
import type { IReturnStatement } from "./IReturnStatement.ts";
|
|
3
|
+
import type { IStatementVisitor } from "./IStatementVisitor.ts";
|
|
4
|
+
|
|
5
|
+
export class ReturnStatement implements IReturnStatement {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly parameters: Parameter[];
|
|
8
|
+
|
|
9
|
+
constructor(name: string, parameters: Parameter[]) {
|
|
10
|
+
this.name = name;
|
|
11
|
+
this.parameters = parameters;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
accept = (visitor: IStatementVisitor): string => visitor.visit(this);
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ParameterDirection } from "../ParameterDirection.ts";
|
|
2
|
+
import type { Parameter } from "../Parameter.ts";
|
|
3
|
+
import type { ReturnStatement } from "./ReturnStatement.ts";
|
|
4
|
+
|
|
5
|
+
const args = (parameters: Parameter[]): string =>
|
|
6
|
+
parameters
|
|
7
|
+
.filter((parameter) => parameter.direction !== ParameterDirection.ReturnValue)
|
|
8
|
+
.map((parameter) => `$${parameter.name}`)
|
|
9
|
+
.join(", ");
|
|
10
|
+
|
|
11
|
+
export class ReturnStatementTextRenderer {
|
|
12
|
+
render(statement: ReturnStatement): string {
|
|
13
|
+
return `SELECT ${statement.name}(${args(statement.parameters)})`;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { DefaultStatementTextRenderer, SelectInsertedIdStatement } from "../index.ts";
|
|
3
|
+
|
|
4
|
+
describe("SelectInsertedIdStatement", () => {
|
|
5
|
+
it("requires a provider implementation", () => {
|
|
6
|
+
const statement = new SelectInsertedIdStatement("users", "id");
|
|
7
|
+
expect(() => DefaultStatementTextRenderer.instance.render(statement)).toThrow(
|
|
8
|
+
"provider must implement SelectInsertIdStatement",
|
|
9
|
+
);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IStatement } from "./IStatement.ts";
|
|
2
|
+
import type { IStatementVisitor } from "./IStatementVisitor.ts";
|
|
3
|
+
|
|
4
|
+
export class SelectInsertedIdStatement implements IStatement {
|
|
5
|
+
constructor(
|
|
6
|
+
readonly table: string,
|
|
7
|
+
readonly column: string,
|
|
8
|
+
) {}
|
|
9
|
+
|
|
10
|
+
accept = (visitor: IStatementVisitor): string => visitor.visit(this);
|
|
11
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SelectInsertedIdStatement } from "./SelectInsertedIdStatement.ts";
|
|
2
|
+
|
|
3
|
+
export class SelectInsertedIdStatementTextRenderer {
|
|
4
|
+
render(_statement: SelectInsertedIdStatement): string {
|
|
5
|
+
throw new Error("provider must implement SelectInsertIdStatement");
|
|
6
|
+
}
|
|
7
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ISelectStatement } from "./ISelectStatement.ts";
|
|
2
|
+
import type { IStatementVisitor } from "./IStatementVisitor.ts";
|
|
3
|
+
import type { IWhere } from "./IWhere.ts";
|
|
4
|
+
import type { Join } from "./Join.ts";
|
|
5
|
+
import type { OrderBy } from "./OrderBy.ts";
|
|
6
|
+
import type { SelectStatementOptions } from "./SelectStatementOptions.ts";
|
|
7
|
+
|
|
8
|
+
export class SelectStatement implements ISelectStatement {
|
|
9
|
+
readonly where?: IWhere;
|
|
10
|
+
readonly distinct: boolean;
|
|
11
|
+
readonly table?: string;
|
|
12
|
+
readonly fields: string[];
|
|
13
|
+
readonly joins: Join[];
|
|
14
|
+
readonly groupBy: string[];
|
|
15
|
+
readonly having?: IWhere;
|
|
16
|
+
readonly orderBy: OrderBy[];
|
|
17
|
+
readonly limit?: number;
|
|
18
|
+
readonly offset?: number;
|
|
19
|
+
|
|
20
|
+
constructor(options: SelectStatementOptions) {
|
|
21
|
+
this.where = options.where;
|
|
22
|
+
this.distinct = options.distinct ?? false;
|
|
23
|
+
this.table = options.table;
|
|
24
|
+
this.fields = options.fields ?? [];
|
|
25
|
+
this.joins = options.joins ?? [];
|
|
26
|
+
this.groupBy = options.groupBy ?? [];
|
|
27
|
+
this.having = options.having;
|
|
28
|
+
this.orderBy = options.orderBy ?? [];
|
|
29
|
+
this.limit = options.limit;
|
|
30
|
+
this.offset = options.offset;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
accept = (visitor: IStatementVisitor): string => visitor.visit(this);
|
|
34
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Join } from "./Join.ts";
|
|
2
|
+
import type { IWhere } from "./IWhere.ts";
|
|
3
|
+
import type { OrderBy } from "./OrderBy.ts";
|
|
4
|
+
|
|
5
|
+
export type SelectStatementOptions = {
|
|
6
|
+
table?: string;
|
|
7
|
+
fields?: string[];
|
|
8
|
+
distinct?: boolean;
|
|
9
|
+
where?: IWhere;
|
|
10
|
+
joins?: Join[];
|
|
11
|
+
groupBy?: string[];
|
|
12
|
+
having?: IWhere;
|
|
13
|
+
orderBy?: OrderBy[];
|
|
14
|
+
limit?: number;
|
|
15
|
+
offset?: number;
|
|
16
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { IWhere } from "./IWhere.ts";
|
|
2
|
+
import type { Join, JoinKind } from "./Join.ts";
|
|
3
|
+
import { orderText, type OrderBy } from "./OrderBy.ts";
|
|
4
|
+
import type { SelectStatement } from "./SelectStatement.ts";
|
|
5
|
+
import type { StatementTextRenderer } from "./StatementTextRenderer.ts";
|
|
6
|
+
import { Where } from "./Where.ts";
|
|
7
|
+
|
|
8
|
+
export class SelectStatementTextRenderer {
|
|
9
|
+
constructor(private readonly text: StatementTextRenderer) {}
|
|
10
|
+
|
|
11
|
+
render(statement: SelectStatement): string {
|
|
12
|
+
return `SELECT ${statement.distinct ? "DISTINCT " : ""}${
|
|
13
|
+
statement.fields.length === 0 ? "*" : statement.fields.join(", ")
|
|
14
|
+
} FROM ${statement.table}${this.joinSql(statement.joins)}${this.whereSql(statement.where)}${this.groupSql(statement.groupBy)}${this.havingSql(statement.having)}${this.orderSql(statement.orderBy)}${this.limit(statement.limit)}${this.offset(statement.offset)}`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
protected whereSql(where?: IWhere): string {
|
|
18
|
+
return where ? ` WHERE ${this.text.render(where)}` : "";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
protected havingSql(having?: IWhere): string {
|
|
22
|
+
return having ? ` HAVING ${this.text.render(having)}` : "";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
protected groupSql(columns?: string[]): string {
|
|
26
|
+
return !columns || columns.length === 0 ? "" : ` GROUP BY ${columns.join(", ")}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
protected orderSql(order?: OrderBy[]): string {
|
|
30
|
+
return !order || order.length === 0 ? "" : ` ORDER BY ${order.map(orderText).join(", ")}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
protected limit(limit?: number): string {
|
|
34
|
+
return this.bound("LIMIT", limit);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected offset(offset?: number): string {
|
|
38
|
+
return this.bound("OFFSET", offset);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
protected bound(keyword: string, value?: number): string {
|
|
42
|
+
if (value === undefined) return "";
|
|
43
|
+
if (value < 0) throw new Error(`negative ${keyword.toLowerCase()}`);
|
|
44
|
+
return ` ${keyword} ${value}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
protected joinSql(joins?: Join[]): string {
|
|
48
|
+
if (!joins || joins.length === 0) return "";
|
|
49
|
+
return joins
|
|
50
|
+
.map((join) =>
|
|
51
|
+
join.kind === "cross"
|
|
52
|
+
? ` CROSS JOIN ${join.table}`
|
|
53
|
+
: ` ${this.keyword(join.kind)} ${join.table} ON ${this.text.render(
|
|
54
|
+
new Where(join.on ?? (() => { throw new Error("empty join"); })()),
|
|
55
|
+
)}`,
|
|
56
|
+
)
|
|
57
|
+
.join("");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
protected keyword(kind: JoinKind): string {
|
|
61
|
+
return (
|
|
62
|
+
{
|
|
63
|
+
inner: "INNER JOIN",
|
|
64
|
+
left: "LEFT JOIN",
|
|
65
|
+
right: "RIGHT JOIN",
|
|
66
|
+
full: "FULL JOIN",
|
|
67
|
+
cross: "CROSS JOIN",
|
|
68
|
+
} as Record<JoinKind, string>
|
|
69
|
+
)[kind];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
Aggregate,
|
|
4
|
+
CheckConstraint,
|
|
5
|
+
ColumnDefault,
|
|
6
|
+
CreateIndexStatement,
|
|
7
|
+
CreateTableStatement,
|
|
8
|
+
DeleteStatement,
|
|
9
|
+
ForeignKey,
|
|
10
|
+
InsertStatement,
|
|
11
|
+
Join,
|
|
12
|
+
NotNull,
|
|
13
|
+
Operator,
|
|
14
|
+
OrderBy,
|
|
15
|
+
PrimaryKey,
|
|
16
|
+
SelectStatement,
|
|
17
|
+
ReferentialAction,
|
|
18
|
+
ReturnStatement,
|
|
19
|
+
UniqueConstraint,
|
|
20
|
+
ExecuteStoredProcedureStatement,
|
|
21
|
+
UpdateStatement,
|
|
22
|
+
WhereText,
|
|
23
|
+
Where,
|
|
24
|
+
DefaultStatementTextRenderer,
|
|
25
|
+
} from "../index.ts";
|
|
26
|
+
|
|
27
|
+
describe("statement compile", () => {
|
|
28
|
+
it("wraps query text and an optional where", () => {
|
|
29
|
+
const select = new SelectStatement({ table: "dual", fields: ["1"] });
|
|
30
|
+
const byId = new WhereText("id = 1");
|
|
31
|
+
const withWhere = new SelectStatement({ table: "dual", fields: ["1"], where: byId });
|
|
32
|
+
expect(DefaultStatementTextRenderer.instance.render(select)).toBe("SELECT 1 FROM dual");
|
|
33
|
+
expect(select.where).toBeUndefined();
|
|
34
|
+
expect(withWhere.where).toBe(byId);
|
|
35
|
+
expect(DefaultStatementTextRenderer.instance.render(byId)).toBe("id = 1");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("compiles a select", () => {
|
|
39
|
+
const where = new Where(
|
|
40
|
+
new Operator.And(new Operator.Equals("id", 1), new Operator.GreaterThan("age", 18)),
|
|
41
|
+
);
|
|
42
|
+
const query = new SelectStatement({ table: "users", fields: ["id", "name"], where });
|
|
43
|
+
expect(DefaultStatementTextRenderer.instance.render(query)).toBe(
|
|
44
|
+
"SELECT id, name FROM users WHERE id = $id AND age > $age",
|
|
45
|
+
);
|
|
46
|
+
expect(query.where).toBe(where);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("joins tables", () => {
|
|
50
|
+
const query = new SelectStatement({
|
|
51
|
+
table: "users",
|
|
52
|
+
fields: ["users.id"],
|
|
53
|
+
where: new Where(new Operator.Equals("users.id", 1)),
|
|
54
|
+
joins: [
|
|
55
|
+
Join.inner("orders", "users.id", "orders.user_id"),
|
|
56
|
+
Join.left("payments", "orders.id", "payments.order_id"),
|
|
57
|
+
Join.right("profiles", "users.id", "profiles.user_id"),
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
expect(DefaultStatementTextRenderer.instance.render(query)).toBe(
|
|
61
|
+
"SELECT users.id FROM users INNER JOIN orders ON users.id = orders.user_id LEFT JOIN payments ON orders.id = payments.order_id RIGHT JOIN profiles ON users.id = profiles.user_id WHERE users.id = $users.id",
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("groups aggregates orders and limits", () => {
|
|
66
|
+
const grouped = new SelectStatement({
|
|
67
|
+
table: "orders",
|
|
68
|
+
fields: ["status", Aggregate.count("*", "n"), Aggregate.sum("amount", "total")],
|
|
69
|
+
where: new Where(new Operator.Equals("status", "open")),
|
|
70
|
+
joins: [Join.inner("customers", "orders.customer_id", "customers.id")],
|
|
71
|
+
groupBy: ["status"],
|
|
72
|
+
orderBy: [OrderBy.desc("total"), OrderBy.asc("status")],
|
|
73
|
+
limit: 10,
|
|
74
|
+
});
|
|
75
|
+
expect(DefaultStatementTextRenderer.instance.render(grouped)).toBe(
|
|
76
|
+
"SELECT status, COUNT(*) AS n, SUM(amount) AS total FROM orders INNER JOIN customers ON orders.customer_id = customers.id WHERE status = $status GROUP BY status ORDER BY total DESC, status ASC LIMIT 10",
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("groups rows", () => {
|
|
81
|
+
const byStatus = new SelectStatement({ table: "users", fields: ["id"], groupBy: ["id"] });
|
|
82
|
+
expect(DefaultStatementTextRenderer.instance.render(byStatus)).toBe("SELECT id FROM users GROUP BY id");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("aggregates without grouping", () => {
|
|
86
|
+
const bounds = new SelectStatement({ table: "users", fields: [Aggregate.min("n"), Aggregate.max("n")] });
|
|
87
|
+
expect(DefaultStatementTextRenderer.instance.render(bounds)).toBe("SELECT MIN(n), MAX(n) FROM users");
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("orders rows", () => {
|
|
91
|
+
const ordered = new SelectStatement({
|
|
92
|
+
table: "users",
|
|
93
|
+
fields: ["id"],
|
|
94
|
+
orderBy: [OrderBy.asc("id"), OrderBy.desc("name")],
|
|
95
|
+
});
|
|
96
|
+
expect(DefaultStatementTextRenderer.instance.render(ordered)).toBe(
|
|
97
|
+
"SELECT id FROM users ORDER BY id ASC, name DESC",
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("limits rows", () => {
|
|
102
|
+
const limited = new SelectStatement({ table: "users", fields: ["id"], limit: 10 });
|
|
103
|
+
expect(DefaultStatementTextRenderer.instance.render(limited)).toBe("SELECT id FROM users LIMIT 10");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("compiles an insert", () => {
|
|
107
|
+
const fields = [
|
|
108
|
+
{ name: "id", value: 1 },
|
|
109
|
+
{ name: "name", value: "a" },
|
|
110
|
+
];
|
|
111
|
+
const insert = new InsertStatement("users", fields);
|
|
112
|
+
expect(DefaultStatementTextRenderer.instance.render(insert)).toBe(
|
|
113
|
+
"INSERT INTO users (id, name) VALUES ($id, $name)",
|
|
114
|
+
);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it("compiles an update", () => {
|
|
118
|
+
const fields = [
|
|
119
|
+
{ name: "id", value: 1 },
|
|
120
|
+
{ name: "name", value: "a" },
|
|
121
|
+
];
|
|
122
|
+
const where = new Where(
|
|
123
|
+
new Operator.And(new Operator.Equals("id", 1), new Operator.GreaterThan("age", 18)),
|
|
124
|
+
);
|
|
125
|
+
const update = new UpdateStatement("users", fields, where);
|
|
126
|
+
expect(DefaultStatementTextRenderer.instance.render(update)).toBe(
|
|
127
|
+
"UPDATE users SET id = $id, name = $name WHERE id = $id AND age > $age",
|
|
128
|
+
);
|
|
129
|
+
expect(update.where).toBe(where);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("compiles a delete", () => {
|
|
133
|
+
const where = new Where(
|
|
134
|
+
new Operator.And(new Operator.Equals("id", 1), new Operator.GreaterThan("age", 18)),
|
|
135
|
+
);
|
|
136
|
+
const del = new DeleteStatement("users", where);
|
|
137
|
+
expect(DefaultStatementTextRenderer.instance.render(del)).toBe(
|
|
138
|
+
"DELETE FROM users WHERE id = $id AND age > $age",
|
|
139
|
+
);
|
|
140
|
+
expect(del.where).toBe(where);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("compiles a create table", () => {
|
|
144
|
+
const createTable = new CreateTableStatement("users", [
|
|
145
|
+
{ name: "id", type: "INTEGER" },
|
|
146
|
+
{ name: "name", type: "TEXT" },
|
|
147
|
+
]);
|
|
148
|
+
expect(DefaultStatementTextRenderer.instance.render(createTable)).toBe(
|
|
149
|
+
"CREATE TABLE users (id INTEGER, name TEXT)",
|
|
150
|
+
);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("compiles named constraints", () => {
|
|
154
|
+
const namedTable = new CreateTableStatement(
|
|
155
|
+
"orders",
|
|
156
|
+
[
|
|
157
|
+
{ name: "id", type: "INTEGER", default: new ColumnDefault("0", "df_id"), notNull: new NotNull("nn_id") },
|
|
158
|
+
{ name: "tenant_id", type: "INTEGER" },
|
|
159
|
+
{ name: "user_id", type: "INTEGER" },
|
|
160
|
+
{ name: "qty", type: "INTEGER" },
|
|
161
|
+
],
|
|
162
|
+
[
|
|
163
|
+
new PrimaryKey("pk_orders", ["id", "tenant_id"]),
|
|
164
|
+
new ForeignKey("fk_orders_user", ["user_id"], "users", ["id"], ReferentialAction.Cascade),
|
|
165
|
+
new UniqueConstraint("uq_orders_user", ["user_id"]),
|
|
166
|
+
new CheckConstraint("chk_orders_qty", "qty > 0"),
|
|
167
|
+
],
|
|
168
|
+
);
|
|
169
|
+
expect(DefaultStatementTextRenderer.instance.render(namedTable)).toBe(
|
|
170
|
+
"CREATE TABLE orders (id INTEGER CONSTRAINT df_id DEFAULT 0 CONSTRAINT nn_id NOT NULL, tenant_id INTEGER, user_id INTEGER, qty INTEGER, CONSTRAINT pk_orders PRIMARY KEY (id, tenant_id), CONSTRAINT fk_orders_user FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE, CONSTRAINT uq_orders_user UNIQUE (user_id), CONSTRAINT chk_orders_qty CHECK (qty > 0))",
|
|
171
|
+
);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it("compiles a create index", () => {
|
|
175
|
+
const createIndex = new CreateIndexStatement("idx_orders_user", "orders", ["user_id"]);
|
|
176
|
+
expect(DefaultStatementTextRenderer.instance.render(createIndex)).toBe(
|
|
177
|
+
"CREATE INDEX idx_orders_user ON orders (user_id)",
|
|
178
|
+
);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("compiles a create unique index", () => {
|
|
182
|
+
const createIndex = new CreateIndexStatement("uq_orders_code", "orders", ["code"], true);
|
|
183
|
+
expect(DefaultStatementTextRenderer.instance.render(createIndex)).toBe(
|
|
184
|
+
"CREATE UNIQUE INDEX uq_orders_code ON orders (code)",
|
|
185
|
+
);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("compiles a call", () => {
|
|
189
|
+
const fields = [
|
|
190
|
+
{ name: "id", value: 1 },
|
|
191
|
+
{ name: "name", value: "a" },
|
|
192
|
+
];
|
|
193
|
+
const call = new ExecuteStoredProcedureStatement("save", fields);
|
|
194
|
+
expect(DefaultStatementTextRenderer.instance.render(call)).toBe("CALL save($id, $name)");
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("compiles a select function call", () => {
|
|
198
|
+
const fields = [
|
|
199
|
+
{ name: "id", value: 1 },
|
|
200
|
+
{ name: "name", value: "a" },
|
|
201
|
+
];
|
|
202
|
+
const ret = new ReturnStatement("add", fields);
|
|
203
|
+
expect(DefaultStatementTextRenderer.instance.render(ret)).toBe("SELECT add($id, $name)");
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("renders compare groups not and in", () => {
|
|
207
|
+
const where = new Where(
|
|
208
|
+
new Operator.And(new Operator.Equals("id", 1), new Operator.GreaterThan("age", 18)),
|
|
209
|
+
);
|
|
210
|
+
const inIds = new Where(new Operator.In("id", [1, 2]));
|
|
211
|
+
expect(DefaultStatementTextRenderer.instance.render(where)).toBe("id = $id AND age > $age");
|
|
212
|
+
expect(DefaultStatementTextRenderer.instance.render(inIds)).toBe("id IN ($id_0, $id_1)");
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it("compare tree", () => {
|
|
216
|
+
const where = new Where(
|
|
217
|
+
new Operator.And(new Operator.Equals("id", 1), new Operator.GreaterThan("age", 18)),
|
|
218
|
+
);
|
|
219
|
+
expect(DefaultStatementTextRenderer.instance.render(where)).toBe("id = $id AND age > $age");
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it("attaches where to a query", () => {
|
|
223
|
+
const where = new Where(
|
|
224
|
+
new Operator.And(new Operator.Equals("id", 1), new Operator.GreaterThan("age", 18)),
|
|
225
|
+
);
|
|
226
|
+
const query = new SelectStatement({ table: "users", fields: ["id", "name"], where });
|
|
227
|
+
expect(DefaultStatementTextRenderer.instance.render(query)).toBe(
|
|
228
|
+
"SELECT id, name FROM users WHERE id = $id AND age > $age",
|
|
229
|
+
);
|
|
230
|
+
});
|
|
231
|
+
});
|