Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f27b647eb0 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,6 +6,3 @@ nto-cli/
|
||||
/**/node_modules/
|
||||
/**/dist/
|
||||
.xlsx
|
||||
build/appimage
|
||||
build/nfpm
|
||||
build/nsis
|
||||
4
.idea/.gigateam/gigateam.properties
generated
Normal file
4
.idea/.gigateam/gigateam.properties
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
## changed at Sun Feb 09 09:09:47 KRAT 2025
|
||||
#Sun Feb 09 09:09:47 KRAT 2025
|
||||
com.dtl.jetbrains.utils.IdeaSlowOperationsAssertionUtils.isUnreadDefault=false
|
||||
com.dtl.jetbrains.utils.IdeaSlowOperationsAssertionUtils.defaultValue=false
|
||||
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
4
.idea/boilerplate.iml
generated
4
.idea/boilerplate.iml
generated
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
</module>
|
||||
31
.idea/codeStyles/Project.xml
generated
Normal file
31
.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,31 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<DBN-PSQL>
|
||||
<case-options enabled="true">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false" />
|
||||
</DBN-PSQL>
|
||||
<DBN-SQL>
|
||||
<case-options enabled="true">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false">
|
||||
<option name="STATEMENT_SPACING" value="one_line" />
|
||||
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
|
||||
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
|
||||
</formatting-settings>
|
||||
</DBN-SQL>
|
||||
<ScalaCodeStyleSettings>
|
||||
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
|
||||
</ScalaCodeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
||||
405
.idea/dbnavigator.xml
generated
Normal file
405
.idea/dbnavigator.xml
generated
Normal file
@@ -0,0 +1,405 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DBNavigator.Project.DatabaseFileManager">
|
||||
<open-files />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.Settings">
|
||||
<connections />
|
||||
<browser-settings>
|
||||
<general>
|
||||
<display-mode value="TABBED" />
|
||||
<navigation-history-size value="100" />
|
||||
<show-object-details value="false" />
|
||||
<enable-sticky-paths value="true" />
|
||||
</general>
|
||||
<filters>
|
||||
<object-type-filter>
|
||||
<object-type name="SCHEMA" enabled="true" />
|
||||
<object-type name="USER" enabled="true" />
|
||||
<object-type name="ROLE" enabled="true" />
|
||||
<object-type name="PRIVILEGE" enabled="true" />
|
||||
<object-type name="CHARSET" enabled="true" />
|
||||
<object-type name="TABLE" enabled="true" />
|
||||
<object-type name="VIEW" enabled="true" />
|
||||
<object-type name="MATERIALIZED_VIEW" enabled="true" />
|
||||
<object-type name="NESTED_TABLE" enabled="true" />
|
||||
<object-type name="COLUMN" enabled="true" />
|
||||
<object-type name="INDEX" enabled="true" />
|
||||
<object-type name="CONSTRAINT" enabled="true" />
|
||||
<object-type name="DATASET_TRIGGER" enabled="true" />
|
||||
<object-type name="DATABASE_TRIGGER" enabled="true" />
|
||||
<object-type name="SYNONYM" enabled="true" />
|
||||
<object-type name="SEQUENCE" enabled="true" />
|
||||
<object-type name="PROCEDURE" enabled="true" />
|
||||
<object-type name="FUNCTION" enabled="true" />
|
||||
<object-type name="PACKAGE" enabled="true" />
|
||||
<object-type name="TYPE" enabled="true" />
|
||||
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
|
||||
<object-type name="ARGUMENT" enabled="true" />
|
||||
<object-type name="DIMENSION" enabled="true" />
|
||||
<object-type name="CLUSTER" enabled="true" />
|
||||
<object-type name="DBLINK" enabled="true" />
|
||||
</object-type-filter>
|
||||
</filters>
|
||||
<sorting>
|
||||
<object-type name="COLUMN" sorting-type="NAME" />
|
||||
<object-type name="FUNCTION" sorting-type="NAME" />
|
||||
<object-type name="PROCEDURE" sorting-type="NAME" />
|
||||
<object-type name="ARGUMENT" sorting-type="POSITION" />
|
||||
<object-type name="TYPE ATTRIBUTE" sorting-type="POSITION" />
|
||||
</sorting>
|
||||
<default-editors>
|
||||
<object-type name="VIEW" editor-type="SELECTION" />
|
||||
<object-type name="PACKAGE" editor-type="SELECTION" />
|
||||
<object-type name="TYPE" editor-type="SELECTION" />
|
||||
</default-editors>
|
||||
</browser-settings>
|
||||
<navigation-settings>
|
||||
<lookup-filters>
|
||||
<lookup-objects>
|
||||
<object-type name="SCHEMA" enabled="true" />
|
||||
<object-type name="USER" enabled="false" />
|
||||
<object-type name="ROLE" enabled="false" />
|
||||
<object-type name="PRIVILEGE" enabled="false" />
|
||||
<object-type name="CHARSET" enabled="false" />
|
||||
<object-type name="TABLE" enabled="true" />
|
||||
<object-type name="VIEW" enabled="true" />
|
||||
<object-type name="MATERIALIZED VIEW" enabled="true" />
|
||||
<object-type name="INDEX" enabled="true" />
|
||||
<object-type name="CONSTRAINT" enabled="true" />
|
||||
<object-type name="DATASET TRIGGER" enabled="true" />
|
||||
<object-type name="DATABASE TRIGGER" enabled="true" />
|
||||
<object-type name="SYNONYM" enabled="false" />
|
||||
<object-type name="SEQUENCE" enabled="true" />
|
||||
<object-type name="PROCEDURE" enabled="true" />
|
||||
<object-type name="FUNCTION" enabled="true" />
|
||||
<object-type name="PACKAGE" enabled="true" />
|
||||
<object-type name="TYPE" enabled="true" />
|
||||
<object-type name="DIMENSION" enabled="false" />
|
||||
<object-type name="CLUSTER" enabled="false" />
|
||||
<object-type name="DBLINK" enabled="true" />
|
||||
</lookup-objects>
|
||||
<force-database-load value="false" />
|
||||
<prompt-connection-selection value="true" />
|
||||
<prompt-schema-selection value="true" />
|
||||
</lookup-filters>
|
||||
</navigation-settings>
|
||||
<dataset-grid-settings>
|
||||
<general>
|
||||
<enable-zooming value="true" />
|
||||
<enable-column-tooltip value="true" />
|
||||
</general>
|
||||
<sorting>
|
||||
<nulls-first value="true" />
|
||||
<max-sorting-columns value="4" />
|
||||
</sorting>
|
||||
<audit-columns>
|
||||
<column-names value="" />
|
||||
<visible value="true" />
|
||||
<editable value="false" />
|
||||
</audit-columns>
|
||||
</dataset-grid-settings>
|
||||
<dataset-editor-settings>
|
||||
<text-editor-popup>
|
||||
<active value="false" />
|
||||
<active-if-empty value="false" />
|
||||
<data-length-threshold value="100" />
|
||||
<popup-delay value="1000" />
|
||||
</text-editor-popup>
|
||||
<values-actions-popup>
|
||||
<show-popup-button value="true" />
|
||||
<element-count-threshold value="1000" />
|
||||
<data-length-threshold value="250" />
|
||||
</values-actions-popup>
|
||||
<general>
|
||||
<fetch-block-size value="100" />
|
||||
<fetch-timeout value="30" />
|
||||
<trim-whitespaces value="true" />
|
||||
<convert-empty-strings-to-null value="true" />
|
||||
<select-content-on-cell-edit value="true" />
|
||||
<large-value-preview-active value="true" />
|
||||
</general>
|
||||
<filters>
|
||||
<prompt-filter-dialog value="true" />
|
||||
<default-filter-type value="BASIC" />
|
||||
</filters>
|
||||
<qualified-text-editor text-length-threshold="300">
|
||||
<content-types>
|
||||
<content-type name="Text" enabled="true" />
|
||||
<content-type name="Properties" enabled="true" />
|
||||
<content-type name="XML" enabled="true" />
|
||||
<content-type name="DTD" enabled="true" />
|
||||
<content-type name="HTML" enabled="true" />
|
||||
<content-type name="XHTML" enabled="true" />
|
||||
<content-type name="CSS" enabled="true" />
|
||||
<content-type name="Java" enabled="true" />
|
||||
<content-type name="SQL" enabled="true" />
|
||||
<content-type name="PL/SQL" enabled="true" />
|
||||
<content-type name="JavaScript" enabled="true" />
|
||||
<content-type name="JSON" enabled="true" />
|
||||
<content-type name="JSON5" enabled="true" />
|
||||
<content-type name="Groovy" enabled="true" />
|
||||
<content-type name="YAML" enabled="true" />
|
||||
<content-type name="Manifest" enabled="true" />
|
||||
</content-types>
|
||||
</qualified-text-editor>
|
||||
<record-navigation>
|
||||
<navigation-target value="VIEWER" />
|
||||
</record-navigation>
|
||||
</dataset-editor-settings>
|
||||
<code-editor-settings>
|
||||
<general>
|
||||
<show-object-navigation-gutter value="false" />
|
||||
<show-spec-declaration-navigation-gutter value="true" />
|
||||
<enable-spellchecking value="true" />
|
||||
<enable-reference-spellchecking value="false" />
|
||||
</general>
|
||||
<confirmations>
|
||||
<save-changes value="false" />
|
||||
<revert-changes value="true" />
|
||||
<exit-on-changes value="ASK" />
|
||||
</confirmations>
|
||||
</code-editor-settings>
|
||||
<code-completion-settings>
|
||||
<filters>
|
||||
<basic-filter>
|
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||
<filter-element type="OBJECT" id="role" selected="true" />
|
||||
<filter-element type="OBJECT" id="user" selected="true" />
|
||||
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||
<user-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</user-schema>
|
||||
<public-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="false" />
|
||||
<filter-element type="OBJECT" id="view" selected="false" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="false" />
|
||||
<filter-element type="OBJECT" id="index" selected="false" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="false" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="false" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="false" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="false" />
|
||||
<filter-element type="OBJECT" id="function" selected="false" />
|
||||
<filter-element type="OBJECT" id="package" selected="false" />
|
||||
<filter-element type="OBJECT" id="type" selected="false" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="false" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="false" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="false" />
|
||||
</public-schema>
|
||||
<any-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</any-schema>
|
||||
</basic-filter>
|
||||
<extended-filter>
|
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||
<filter-element type="OBJECT" id="user" selected="true" />
|
||||
<filter-element type="OBJECT" id="role" selected="true" />
|
||||
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||
<user-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</user-schema>
|
||||
<public-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</public-schema>
|
||||
<any-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</any-schema>
|
||||
</extended-filter>
|
||||
</filters>
|
||||
<sorting enabled="true">
|
||||
<sorting-element type="RESERVED_WORD" id="keyword" />
|
||||
<sorting-element type="RESERVED_WORD" id="datatype" />
|
||||
<sorting-element type="OBJECT" id="column" />
|
||||
<sorting-element type="OBJECT" id="table" />
|
||||
<sorting-element type="OBJECT" id="view" />
|
||||
<sorting-element type="OBJECT" id="materialized view" />
|
||||
<sorting-element type="OBJECT" id="index" />
|
||||
<sorting-element type="OBJECT" id="constraint" />
|
||||
<sorting-element type="OBJECT" id="trigger" />
|
||||
<sorting-element type="OBJECT" id="synonym" />
|
||||
<sorting-element type="OBJECT" id="sequence" />
|
||||
<sorting-element type="OBJECT" id="procedure" />
|
||||
<sorting-element type="OBJECT" id="function" />
|
||||
<sorting-element type="OBJECT" id="package" />
|
||||
<sorting-element type="OBJECT" id="type" />
|
||||
<sorting-element type="OBJECT" id="dimension" />
|
||||
<sorting-element type="OBJECT" id="cluster" />
|
||||
<sorting-element type="OBJECT" id="dblink" />
|
||||
<sorting-element type="OBJECT" id="schema" />
|
||||
<sorting-element type="OBJECT" id="role" />
|
||||
<sorting-element type="OBJECT" id="user" />
|
||||
<sorting-element type="RESERVED_WORD" id="function" />
|
||||
<sorting-element type="RESERVED_WORD" id="parameter" />
|
||||
</sorting>
|
||||
<format>
|
||||
<enforce-code-style-case value="true" />
|
||||
</format>
|
||||
</code-completion-settings>
|
||||
<execution-engine-settings>
|
||||
<statement-execution>
|
||||
<fetch-block-size value="100" />
|
||||
<execution-timeout value="20" />
|
||||
<debug-execution-timeout value="600" />
|
||||
<focus-result value="false" />
|
||||
<prompt-execution value="false" />
|
||||
</statement-execution>
|
||||
<script-execution>
|
||||
<command-line-interfaces />
|
||||
<execution-timeout value="300" />
|
||||
</script-execution>
|
||||
<method-execution>
|
||||
<execution-timeout value="30" />
|
||||
<debug-execution-timeout value="600" />
|
||||
<parameter-history-size value="10" />
|
||||
</method-execution>
|
||||
</execution-engine-settings>
|
||||
<operation-settings>
|
||||
<transactions>
|
||||
<uncommitted-changes>
|
||||
<on-project-close value="ASK" />
|
||||
<on-disconnect value="ASK" />
|
||||
<on-autocommit-toggle value="ASK" />
|
||||
</uncommitted-changes>
|
||||
<multiple-uncommitted-changes>
|
||||
<on-commit value="ASK" />
|
||||
<on-rollback value="ASK" />
|
||||
</multiple-uncommitted-changes>
|
||||
</transactions>
|
||||
<session-browser>
|
||||
<disconnect-session value="ASK" />
|
||||
<kill-session value="ASK" />
|
||||
<reload-on-filter-change value="false" />
|
||||
</session-browser>
|
||||
<compiler>
|
||||
<compile-type value="KEEP" />
|
||||
<compile-dependencies value="ASK" />
|
||||
<always-show-controls value="false" />
|
||||
</compiler>
|
||||
</operation-settings>
|
||||
<ddl-file-settings>
|
||||
<extensions>
|
||||
<mapping file-type-id="VIEW" extensions="vw" />
|
||||
<mapping file-type-id="TRIGGER" extensions="trg" />
|
||||
<mapping file-type-id="PROCEDURE" extensions="prc" />
|
||||
<mapping file-type-id="FUNCTION" extensions="fnc" />
|
||||
<mapping file-type-id="PACKAGE" extensions="pkg" />
|
||||
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
|
||||
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
|
||||
<mapping file-type-id="TYPE" extensions="tpe" />
|
||||
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
|
||||
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
|
||||
</extensions>
|
||||
<general>
|
||||
<lookup-ddl-files value="true" />
|
||||
<create-ddl-files value="false" />
|
||||
<synchronize-ddl-files value="true" />
|
||||
<use-qualified-names value="false" />
|
||||
<make-scripts-rerunnable value="true" />
|
||||
</general>
|
||||
</ddl-file-settings>
|
||||
<general-settings>
|
||||
<regional-settings>
|
||||
<date-format value="MEDIUM" />
|
||||
<number-format value="UNGROUPED" />
|
||||
<locale value="SYSTEM_DEFAULT" />
|
||||
<use-custom-formats value="false" />
|
||||
</regional-settings>
|
||||
<environment>
|
||||
<environment-types>
|
||||
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
|
||||
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
|
||||
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
|
||||
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
|
||||
</environment-types>
|
||||
<visibility-settings>
|
||||
<connection-tabs value="true" />
|
||||
<dialog-headers value="true" />
|
||||
<object-editor-tabs value="true" />
|
||||
<script-editor-tabs value="false" />
|
||||
<execution-result-tabs value="true" />
|
||||
</visibility-settings>
|
||||
</environment>
|
||||
</general-settings>
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/nto_starterkit.iml" filepath="$PROJECT_DIR$/.idea/nto_starterkit.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
9
.idea/nto_starterkit.iml
generated
Normal file
9
.idea/nto_starterkit.iml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
2
.idea/vcs.xml
generated
2
.idea/vcs.xml
generated
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
118
.idea/workspace.xml
generated
118
.idea/workspace.xml
generated
@@ -1,118 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="ALL" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="0f2c8145-9000-45fe-a871-9ff0914e0e13" name="Changes" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/frontend/bindings/app/internal/services/excelmodule.ts" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/frontend/bindings/app/internal/services/index.ts" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/internal/dal/gen.go" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/internal/dal/gen_test.go" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/internal/dal/posts.gen.go" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/internal/dal/posts.gen_test.go" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/main.go" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Go File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="GOROOT" url="file://$USER_HOME$/go/go1.24.1" />
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectCodeStyleSettingsMigration">
|
||||
<option name="version" value="2" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"associatedIndex": 8
|
||||
}</component>
|
||||
<component name="ProjectId" id="2sRWGnZjOMe2yOSS8et0US4qUZq" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"DefaultGoTemplateProperty": "Go File",
|
||||
"Go Build.go build app.executor": "Debug",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"RunOnceActivity.go.formatter.settings.were.checked": "true",
|
||||
"RunOnceActivity.go.migrated.go.modules.settings": "true",
|
||||
"RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
|
||||
"git-widget-placeholder": "main",
|
||||
"go.import.settings.migrated": "true",
|
||||
"go.sdk.automatically.set": "true",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "/home/gogacoder/dev/go/nto/boilerplate",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "go.sdk",
|
||||
"ts.external.directory.path": "/home/gogacoder/dev/go/nto/boilerplate/frontend/node_modules/typescript/lib",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</component>
|
||||
<component name="RecentsManager">
|
||||
<key name="MoveFile.RECENT_KEYS">
|
||||
<recent name="$PROJECT_DIR$/internal/addons/excel" />
|
||||
<recent name="$PROJECT_DIR$/internal/utils" />
|
||||
<recent name="$PROJECT_DIR$/internal/extras" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration name="go build app" type="GoApplicationRunConfiguration" factoryName="Go Application" nameIsGenerated="true">
|
||||
<module name="nto_starterkit" />
|
||||
<working_directory value="$PROJECT_DIR$" />
|
||||
<kind value="PACKAGE" />
|
||||
<package value="app" />
|
||||
<directory value="$PROJECT_DIR$" />
|
||||
<filePath value="$PROJECT_DIR$" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="go build app" type="GoApplicationRunConfiguration" factoryName="Go Application" nameIsGenerated="true">
|
||||
<module name="nto_starterkit" />
|
||||
<working_directory value="$PROJECT_DIR$" />
|
||||
<kind value="PACKAGE" />
|
||||
<package value="app" />
|
||||
<directory value="$PROJECT_DIR$" />
|
||||
<filePath value="$PROJECT_DIR$" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-gosdk-d297c17c1fbd-57c114c3cede-org.jetbrains.plugins.go.sharedIndexes.bundled-GO-243.25659.52" />
|
||||
<option value="bundled-js-predefined-d6986cc7102b-1632447f56bf-JavaScript-GO-243.25659.52" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="0f2c8145-9000-45fe-a871-9ff0914e0e13" name="Changes" comment="" />
|
||||
<created>1739066986825</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1739066986825</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="VgoProject">
|
||||
<settings-migrated>true</settings-migrated>
|
||||
</component>
|
||||
</project>
|
||||
10
LICENSE
10
LICENSE
@@ -1,10 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Georgiy Derbenev & Chabanenko Vladislav
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
45
README.md
45
README.md
@@ -6,9 +6,9 @@
|
||||
- [x] Crud service generator (based on gorm gen)
|
||||
- [ ] Easy init without git repository (like create-nto-app)
|
||||
- [x] Excel export
|
||||
- [x] Models validation logic (callbacks and other stuff)
|
||||
- [ ] Models validation logic (callbacks and other stuff)
|
||||
- [ ] Models [linter](https://git.gogacoder.ru/NTO/gormlint)
|
||||
- [x] Auto-generated frontend
|
||||
- [ ] Auto-generated frontend
|
||||
|
||||
## Установка
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
|
||||
- [Node.js](https://nodejs.org/en)
|
||||
- [Golang](https://go.dev/dl/)
|
||||
- [VSCode](https://code.visualstudio.com/) или [Goland](https://cloud.gogacoder.ru/s/pZJzpeNSprmWDB8)
|
||||
- ~~[UPX](https://github.com/upx/upx/releases/latest) - для сжатия.~~
|
||||
- VSCode или Goland
|
||||
- [UPX](https://github.com/upx/upx/releases/latest) - для сжатия.
|
||||
**Необходимо зазеркалировать с Github и добавить в PATH!!!**
|
||||
- [Git](https://git-scm.com/)
|
||||
- [Obsidian](https://obsidian.md/)
|
||||
- Wails3
|
||||
- MinGw-64 (необязательно): https://jmeubank.github.io/tdm-gcc/
|
||||
- Wails3:`go install -v github.com/wailsapp/wails/v3/cmd/wails3@latest`
|
||||
- MinGw-64: https://jmeubank.github.io/tdm-gcc/
|
||||
**Необходимо зазеркалировать с Github!!!**
|
||||
|
||||
## Разработка
|
||||
|
||||
@@ -33,6 +34,9 @@
|
||||
wails3 dev
|
||||
```
|
||||
|
||||
DevServer также можно открыть по адресу http://localhost:34115.
|
||||
Этот инструмент предоставляет возможность вызывать Go код прямо из инструментов разработчика.
|
||||
|
||||
### Генерация TS биндингов
|
||||
|
||||
Для обновления API для TypeScript используйте команду:
|
||||
@@ -41,36 +45,19 @@ wails3 dev
|
||||
wails3 generate bindings -ts
|
||||
```
|
||||
|
||||
## Начало работы
|
||||
Установите следующие утилиты перед началом работы:
|
||||
```shell
|
||||
go install -v github.com/wailsapp/wails/v3/cmd/wails3@latest
|
||||
```
|
||||
```shell
|
||||
go install github.com/opbnq-q/nto-cli@latest
|
||||
```
|
||||
```shell
|
||||
go install git.gogacoder.ru/NTO/crudgen/cmd/crudgen@latest
|
||||
```
|
||||
|
||||
## Сборка
|
||||
|
||||
Для финальной сборки запустите эту команду в директории проекта:
|
||||
|
||||
На Linux/Mac OS:
|
||||
```
|
||||
PRODUCTION=true wails3 build
|
||||
```
|
||||
|
||||
На Windows:
|
||||
```
|
||||
$env:PRODUCTION="true"; wails3 build
|
||||
go env -w CGO_ENABLED=1
|
||||
wails3 build -clean -upx -v 2 -webview2 embed
|
||||
```
|
||||
|
||||
**Перед релизом не забыть**:
|
||||
- убедиться, что дефолтные данные правильные
|
||||
- убедиться, что приложение запускается
|
||||
- (опционально) поместить все нужные asset'ы в папку assets
|
||||
|
||||
- поместить все нужные asset'ы в папку assets
|
||||
- изменить версию схемы БД (пока не нужно)
|
||||
- приложить сопроводительную записку.
|
||||
|
||||
## Работа без GitHub
|
||||
|
||||
@@ -10,7 +10,6 @@ tasks:
|
||||
- ../dal/*.go
|
||||
cmds:
|
||||
- go run gen.go
|
||||
method: none
|
||||
|
||||
go:gen:crudgen:
|
||||
summary: Runs crudgen for crud generating
|
||||
@@ -22,7 +21,6 @@ tasks:
|
||||
- go:gen:dal
|
||||
cmds:
|
||||
- crudgen -p internal
|
||||
method: none
|
||||
|
||||
go:mod:tidy:
|
||||
summary: Runs `go mod tidy`
|
||||
|
||||
@@ -13,7 +13,7 @@ tasks:
|
||||
cmds:
|
||||
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}
|
||||
vars:
|
||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production" -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l" {{end}}'
|
||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l"{{end}}'
|
||||
env:
|
||||
GOOS: darwin
|
||||
CGO_ENABLED: 1
|
||||
|
||||
@@ -13,7 +13,7 @@ tasks:
|
||||
cmds:
|
||||
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}
|
||||
vars:
|
||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production" -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l" {{end}}'
|
||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l"{{end}}'
|
||||
env:
|
||||
GOOS: linux
|
||||
CGO_ENABLED: 1
|
||||
|
||||
@@ -18,10 +18,10 @@ tasks:
|
||||
- cmd: rm -f *.syso
|
||||
platforms: [linux, darwin]
|
||||
vars:
|
||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags "production" -trimpath -ldflags="-w -s -H windowsgui"{{else}}-gcflags=all="-l" {{end}}'
|
||||
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s -H windowsgui"{{else}}-gcflags=all="-l"{{end}}'
|
||||
env:
|
||||
GOOS: windows
|
||||
CGO_ENABLED: 0
|
||||
CGO_ENABLED: 1
|
||||
GOARCH: '{{.ARCH | default ARCH}}'
|
||||
PRODUCTION: '{{.PRODUCTION | default "false"}}'
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
import * as ExcelModule from "./excelmodule.js";
|
||||
export {
|
||||
ExcelModule
|
||||
};
|
||||
export * from "./models.js";
|
||||
190
frontend/bindings/app/internal/models/models.ts
Normal file
190
frontend/bindings/app/internal/models/models.ts
Normal file
@@ -0,0 +1,190 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import {Create as $Create} from "@wailsio/runtime";
|
||||
|
||||
export class Author {
|
||||
"Id": number;
|
||||
"Name": string;
|
||||
"Posts": Post[];
|
||||
"Comments": Comment[];
|
||||
|
||||
/** Creates a new Author instance. */
|
||||
constructor($$source: Partial<Author> = {}) {
|
||||
if (!("Id" in $$source)) {
|
||||
this["Id"] = 0;
|
||||
}
|
||||
if (!("Name" in $$source)) {
|
||||
this["Name"] = "";
|
||||
}
|
||||
if (!("Posts" in $$source)) {
|
||||
this["Posts"] = [];
|
||||
}
|
||||
if (!("Comments" in $$source)) {
|
||||
this["Comments"] = [];
|
||||
}
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Author instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): Author {
|
||||
const $$createField2_0 = $$createType1;
|
||||
const $$createField3_0 = $$createType3;
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
if ("Posts" in $$parsedSource) {
|
||||
$$parsedSource["Posts"] = $$createField2_0($$parsedSource["Posts"]);
|
||||
}
|
||||
if ("Comments" in $$parsedSource) {
|
||||
$$parsedSource["Comments"] = $$createField3_0($$parsedSource["Comments"]);
|
||||
}
|
||||
return new Author($$parsedSource as Partial<Author>);
|
||||
}
|
||||
}
|
||||
|
||||
export class Comment {
|
||||
"Id": number;
|
||||
"Text": string;
|
||||
"AuthorId": number;
|
||||
"Author": Author;
|
||||
"Posts": Post[];
|
||||
|
||||
/** Creates a new Comment instance. */
|
||||
constructor($$source: Partial<Comment> = {}) {
|
||||
if (!("Id" in $$source)) {
|
||||
this["Id"] = 0;
|
||||
}
|
||||
if (!("Text" in $$source)) {
|
||||
this["Text"] = "";
|
||||
}
|
||||
if (!("AuthorId" in $$source)) {
|
||||
this["AuthorId"] = 0;
|
||||
}
|
||||
if (!("Author" in $$source)) {
|
||||
this["Author"] = (new Author());
|
||||
}
|
||||
if (!("Posts" in $$source)) {
|
||||
this["Posts"] = [];
|
||||
}
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Comment instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): Comment {
|
||||
const $$createField3_0 = $$createType4;
|
||||
const $$createField4_0 = $$createType1;
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
if ("Author" in $$parsedSource) {
|
||||
$$parsedSource["Author"] = $$createField3_0($$parsedSource["Author"]);
|
||||
}
|
||||
if ("Posts" in $$parsedSource) {
|
||||
$$parsedSource["Posts"] = $$createField4_0($$parsedSource["Posts"]);
|
||||
}
|
||||
return new Comment($$parsedSource as Partial<Comment>);
|
||||
}
|
||||
}
|
||||
|
||||
export class Post {
|
||||
"Id": number;
|
||||
"Text": string;
|
||||
"Deadline": number;
|
||||
"CreatedAt": number;
|
||||
"AuthorId": number;
|
||||
"Author": Author;
|
||||
"PostTypeId": number;
|
||||
"PostType": PostType;
|
||||
"Comments": Comment[];
|
||||
|
||||
/** Creates a new Post instance. */
|
||||
constructor($$source: Partial<Post> = {}) {
|
||||
if (!("Id" in $$source)) {
|
||||
this["Id"] = 0;
|
||||
}
|
||||
if (!("Text" in $$source)) {
|
||||
this["Text"] = "";
|
||||
}
|
||||
if (!("Deadline" in $$source)) {
|
||||
this["Deadline"] = 0;
|
||||
}
|
||||
if (!("CreatedAt" in $$source)) {
|
||||
this["CreatedAt"] = 0;
|
||||
}
|
||||
if (!("AuthorId" in $$source)) {
|
||||
this["AuthorId"] = 0;
|
||||
}
|
||||
if (!("Author" in $$source)) {
|
||||
this["Author"] = (new Author());
|
||||
}
|
||||
if (!("PostTypeId" in $$source)) {
|
||||
this["PostTypeId"] = 0;
|
||||
}
|
||||
if (!("PostType" in $$source)) {
|
||||
this["PostType"] = (new PostType());
|
||||
}
|
||||
if (!("Comments" in $$source)) {
|
||||
this["Comments"] = [];
|
||||
}
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Post instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): Post {
|
||||
const $$createField5_0 = $$createType4;
|
||||
const $$createField7_0 = $$createType5;
|
||||
const $$createField8_0 = $$createType3;
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
if ("Author" in $$parsedSource) {
|
||||
$$parsedSource["Author"] = $$createField5_0($$parsedSource["Author"]);
|
||||
}
|
||||
if ("PostType" in $$parsedSource) {
|
||||
$$parsedSource["PostType"] = $$createField7_0($$parsedSource["PostType"]);
|
||||
}
|
||||
if ("Comments" in $$parsedSource) {
|
||||
$$parsedSource["Comments"] = $$createField8_0($$parsedSource["Comments"]);
|
||||
}
|
||||
return new Post($$parsedSource as Partial<Post>);
|
||||
}
|
||||
}
|
||||
|
||||
export class PostType {
|
||||
"Id": number;
|
||||
"Name": string;
|
||||
|
||||
/** Creates a new PostType instance. */
|
||||
constructor($$source: Partial<PostType> = {}) {
|
||||
if (!("Id" in $$source)) {
|
||||
this["Id"] = 0;
|
||||
}
|
||||
if (!("Name" in $$source)) {
|
||||
this["Name"] = "";
|
||||
}
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PostType instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): PostType {
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
return new PostType($$parsedSource as Partial<PostType>);
|
||||
}
|
||||
}
|
||||
|
||||
// Private type creation functions
|
||||
const $$createType0 = Post.createFrom;
|
||||
const $$createType1 = $Create.Array($$createType0);
|
||||
const $$createType2 = Comment.createFrom;
|
||||
const $$createType3 = $Create.Array($$createType2);
|
||||
const $$createType4 = Author.createFrom;
|
||||
const $$createType5 = PostType.createFrom;
|
||||
74
frontend/bindings/app/internal/services/authorservice.ts
Normal file
74
frontend/bindings/app/internal/services/authorservice.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as models$0 from "../models/models.js";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as $models from "./models.js";
|
||||
|
||||
export function Count(): Promise<number> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3969879864) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
export function Create(item: $models.Author): Promise<$models.Author> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3684602449, item) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType0($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function Delete(id: number): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2096845974, id) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
export function GetAll(): Promise<($models.Author | null)[]> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3248293926) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType2($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function GetById(id: number): Promise<$models.Author | null> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1703016211, id) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType1($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function SortedByOrder(fieldsSortOrder: { [_: string]: string }): Promise<($models.Author | null)[]> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3046628691, fieldsSortOrder) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType2($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function Update(item: $models.Author): Promise<$models.Author> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2240704960, item) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType0($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
// Private type creation functions
|
||||
const $$createType0 = models$0.Author.createFrom;
|
||||
const $$createType1 = $Create.Nullable($$createType0);
|
||||
const $$createType2 = $Create.Array($$createType1);
|
||||
74
frontend/bindings/app/internal/services/commentservice.ts
Normal file
74
frontend/bindings/app/internal/services/commentservice.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as models$0 from "../models/models.js";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as $models from "./models.js";
|
||||
|
||||
export function Count(): Promise<number> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3225397984) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
export function Create(item: $models.Comment): Promise<$models.Comment> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(4239106089, item) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType0($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function Delete(id: number): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2553503582, id) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
export function GetAll(): Promise<($models.Comment | null)[]> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1805763390) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType2($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function GetById(id: number): Promise<$models.Comment | null> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3217823099, id) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType1($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function SortedByOrder(fieldsSortOrder: { [_: string]: string }): Promise<($models.Comment | null)[]> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(4244533291, fieldsSortOrder) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType2($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function Update(item: $models.Comment): Promise<$models.Comment> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3080970936, item) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType0($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
// Private type creation functions
|
||||
const $$createType0 = models$0.Comment.createFrom;
|
||||
const $$createType1 = $Create.Nullable($$createType0);
|
||||
const $$createType2 = $Create.Array($$createType1);
|
||||
@@ -6,11 +6,11 @@
|
||||
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
||||
|
||||
export function ExportAllEntities(): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(4195777221) as any;
|
||||
let $resultPromise = $Call.ByID(794946560) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
export function ImportAllEntities(): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2803141560) as any;
|
||||
let $resultPromise = $Call.ByID(2992267629) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
17
frontend/bindings/app/internal/services/index.ts
Normal file
17
frontend/bindings/app/internal/services/index.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
import * as AuthorService from "./authorservice.js";
|
||||
import * as CommentService from "./commentservice.js";
|
||||
import * as ExcelModule from "./excelmodule.js";
|
||||
import * as PostService from "./postservice.js";
|
||||
import * as PostTypeService from "./posttypeservice.js";
|
||||
export {
|
||||
AuthorService,
|
||||
CommentService,
|
||||
ExcelModule,
|
||||
PostService,
|
||||
PostTypeService
|
||||
};
|
||||
|
||||
export * from "./models.js";
|
||||
22
frontend/bindings/app/internal/services/models.ts
Normal file
22
frontend/bindings/app/internal/services/models.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import {Create as $Create} from "@wailsio/runtime";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as models$0 from "../models/models.js";
|
||||
|
||||
export const Author = models$0.Author;
|
||||
export type Author = models$0.Author;
|
||||
|
||||
export const Comment = models$0.Comment;
|
||||
export type Comment = models$0.Comment;
|
||||
|
||||
export const Post = models$0.Post;
|
||||
export type Post = models$0.Post;
|
||||
|
||||
export const PostType = models$0.PostType;
|
||||
export type PostType = models$0.PostType;
|
||||
74
frontend/bindings/app/internal/services/postservice.ts
Normal file
74
frontend/bindings/app/internal/services/postservice.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as models$0 from "../models/models.js";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as $models from "./models.js";
|
||||
|
||||
export function Count(): Promise<number> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3109924027) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
export function Create(item: $models.Post): Promise<$models.Post> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1443399856, item) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType0($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function Delete(id: number): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2924549135, id) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
export function GetAll(): Promise<($models.Post | null)[]> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(65691059) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType2($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function GetById(id: number): Promise<$models.Post | null> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(4074736792, id) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType1($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function SortedByOrder(fieldsSortOrder: { [_: string]: string }): Promise<($models.Post | null)[]> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(471862744, fieldsSortOrder) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType2($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function Update(item: $models.Post): Promise<$models.Post> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(137798821, item) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType0($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
// Private type creation functions
|
||||
const $$createType0 = models$0.Post.createFrom;
|
||||
const $$createType1 = $Create.Nullable($$createType0);
|
||||
const $$createType2 = $Create.Array($$createType1);
|
||||
74
frontend/bindings/app/internal/services/posttypeservice.ts
Normal file
74
frontend/bindings/app/internal/services/posttypeservice.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as models$0 from "../models/models.js";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import * as $models from "./models.js";
|
||||
|
||||
export function Count(): Promise<number> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(554487955) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
export function Create(item: $models.PostType): Promise<$models.PostType> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1092898136, item) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType0($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function Delete(id: number): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2114913543, id) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
|
||||
export function GetAll(): Promise<($models.PostType | null)[]> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(416231387) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType2($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function GetById(id: number): Promise<$models.PostType | null> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(3237123344, id) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType1($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function SortedByOrder(fieldsSortOrder: { [_: string]: string }): Promise<($models.PostType | null)[]> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1097313920, fieldsSortOrder) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType2($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
export function Update(item: $models.PostType): Promise<$models.PostType> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(2773888269, item) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType0($result);
|
||||
}) as any;
|
||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||
return $typingPromise;
|
||||
}
|
||||
|
||||
// Private type creation functions
|
||||
const $$createType0 = models$0.PostType.createFrom;
|
||||
const $$createType1 = $Create.Nullable($$createType0);
|
||||
const $$createType2 = $Create.Array($$createType1);
|
||||
90
frontend/src/author/AuthorScheme.vue
Normal file
90
frontend/src/author/AuthorScheme.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<script setup lang="ts">
|
||||
import Table from "../table/Table.vue";
|
||||
import { onMounted, reactive } from "vue";
|
||||
import { getDefaultValues } from "../utils/structs/defaults.util";
|
||||
import Service from "./author.service.ts";
|
||||
import type { Scheme } from "../types/scheme.type";
|
||||
import { Author } from "../../bindings/app/internal/services";
|
||||
import { SortedByOrder } from "../../bindings/app/internal/services/authorservice.ts";
|
||||
import { ref } from "vue";
|
||||
import type { Validate } from "../types/validate.type";
|
||||
|
||||
import PostService from "../post/post.service.ts";
|
||||
const postService = new PostService();
|
||||
|
||||
import CommentService from "../comment/comment.service.ts";
|
||||
const commentService = new CommentService();
|
||||
|
||||
const service = new Service();
|
||||
|
||||
const items = ref<Author[]>([]);
|
||||
|
||||
const load = async () => {
|
||||
(scheme as any).Posts.type!.nested!.values = await postService.readAll();
|
||||
|
||||
(scheme as any).Comments.type!.nested!.values =
|
||||
await commentService.readAll();
|
||||
|
||||
items.value = await service.readAll();
|
||||
return items.value;
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await load();
|
||||
console.log(await SortedByOrder({"Comments": "DESC"}))
|
||||
});
|
||||
|
||||
const scheme: Scheme<Author> = reactive({
|
||||
entityId: "AuthorId",
|
||||
|
||||
Id: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
},
|
||||
},
|
||||
|
||||
Name: {
|
||||
russian: "Имя",
|
||||
type: {
|
||||
primitive: "string",
|
||||
},
|
||||
},
|
||||
|
||||
Posts: {
|
||||
russian: "Посты",
|
||||
many: true,
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Text"],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Comments: {
|
||||
russian: "Комментарии",
|
||||
many: true,
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Text"],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const getDefaults = () => getDefaultValues(scheme);
|
||||
|
||||
const validate: Validate<Author> = (entity) => {
|
||||
return {
|
||||
status: "success",
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="w-screen h-screen">
|
||||
<Table name="Author" :scheme :service :get-defaults :load :items :validate></Table>
|
||||
</main>
|
||||
</template>
|
||||
36
frontend/src/author/author.service.ts
Normal file
36
frontend/src/author/author.service.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import {
|
||||
GetAll,
|
||||
Create,
|
||||
Delete,
|
||||
GetById,
|
||||
Update,
|
||||
Count,
|
||||
} from "../../bindings/app/internal/services/authorservice.ts";
|
||||
import type { Author } from "../../bindings/app/internal/services";
|
||||
import type { IService } from "../types/service.type.ts";
|
||||
|
||||
export default class AuthorService implements IService<Author> {
|
||||
async read(id: number) {
|
||||
return (await GetById(id)) as Author;
|
||||
}
|
||||
|
||||
async readAll() {
|
||||
return (await GetAll()) as Author[];
|
||||
}
|
||||
|
||||
async create(item: Author) {
|
||||
await Create(item);
|
||||
}
|
||||
|
||||
async delete(id: number) {
|
||||
return await Delete(id);
|
||||
}
|
||||
|
||||
async update(item: Author) {
|
||||
await Update(item);
|
||||
}
|
||||
|
||||
async count() {
|
||||
return await Count();
|
||||
}
|
||||
}
|
||||
93
frontend/src/comment/CommentScheme.vue
Normal file
93
frontend/src/comment/CommentScheme.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<script setup lang="ts">
|
||||
import Table from "../table/Table.vue";
|
||||
import { onMounted, reactive } from "vue";
|
||||
import { getDefaultValues } from "../utils/structs/defaults.util";
|
||||
import Service from "./comment.service.ts";
|
||||
import type { Scheme } from "../types/scheme.type";
|
||||
import { Comment } from "../../bindings/app/internal/services";
|
||||
import { ref } from "vue";
|
||||
import type { Validate } from "../types/validate.type";
|
||||
|
||||
import AuthorService from "../author/author.service.ts";
|
||||
const authorService = new AuthorService();
|
||||
|
||||
import PostService from "../post/post.service.ts";
|
||||
const postService = new PostService();
|
||||
|
||||
const service = new Service();
|
||||
|
||||
const items = ref<Comment[]>([]);
|
||||
|
||||
const load = async () => {
|
||||
(scheme as any).Author.type!.nested!.values = await authorService.readAll();
|
||||
|
||||
(scheme as any).Posts.type!.nested!.values = await postService.readAll();
|
||||
|
||||
items.value = await service.readAll();
|
||||
return items.value;
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
load();
|
||||
});
|
||||
|
||||
const scheme: Scheme<Comment> = reactive({
|
||||
entityId: "CommentId",
|
||||
|
||||
Id: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
},
|
||||
},
|
||||
|
||||
Text: {
|
||||
russian: "Текст",
|
||||
type: {
|
||||
primitive: "string",
|
||||
},
|
||||
},
|
||||
|
||||
AuthorId: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
},
|
||||
},
|
||||
|
||||
Author: {
|
||||
russian: "Автор",
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Name"],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Posts: {
|
||||
russian: "Посты",
|
||||
many: true,
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Text"],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const getDefaults = () => getDefaultValues(scheme);
|
||||
|
||||
const validate: Validate<Comment> = (entity) => {
|
||||
return {
|
||||
status: "success",
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="w-screen h-screen">
|
||||
<Table :scheme :service :get-defaults :load :items :validate></Table>
|
||||
</main>
|
||||
</template>
|
||||
36
frontend/src/comment/comment.service.ts
Normal file
36
frontend/src/comment/comment.service.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import {
|
||||
GetAll,
|
||||
Create,
|
||||
Delete,
|
||||
GetById,
|
||||
Update,
|
||||
Count,
|
||||
} from "../../bindings/app/internal/services/commentservice.ts";
|
||||
import type { Comment } from "../../bindings/app/internal/services";
|
||||
import type { IService } from "../types/service.type.ts";
|
||||
|
||||
export default class CommentService implements IService<Comment> {
|
||||
async read(id: number) {
|
||||
return (await GetById(id)) as Comment;
|
||||
}
|
||||
|
||||
async readAll() {
|
||||
return (await GetAll()) as Comment[];
|
||||
}
|
||||
|
||||
async create(item: Comment) {
|
||||
await Create(item);
|
||||
}
|
||||
|
||||
async delete(id: number) {
|
||||
return await Delete(id);
|
||||
}
|
||||
|
||||
async update(item: Comment) {
|
||||
await Update(item);
|
||||
}
|
||||
|
||||
async count() {
|
||||
return await Count();
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ const pushOrRemove = (option: T) => {
|
||||
} else {
|
||||
selected.value.push(option)
|
||||
}
|
||||
//setNullIds()
|
||||
}
|
||||
|
||||
const setNullIds = () => {
|
||||
@@ -26,11 +27,12 @@ const setNullIds = () => {
|
||||
})
|
||||
}
|
||||
|
||||
//onMounted(setNullIds)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="">
|
||||
<ul class="max-h-48 h-auto overflow-y-auto background rounded-md p-3 w-full native-border">
|
||||
<ul class="max-h-48 h-auto overflow-y-auto background rounded-md p-3 w-full border-gray-500 border">
|
||||
<li v-for="option in options" :key="option.Id" class="flex items-center gap-2">
|
||||
<Checkbox :checked="selected.some(item => item.Id == option.Id)" @click="pushOrRemove(option)" />
|
||||
<label :for="option.Id.toString()">{{ structView(option, path) }}</label>
|
||||
|
||||
@@ -1,40 +1,34 @@
|
||||
<script setup lang="ts">
|
||||
import { Button } from 'primevue';
|
||||
import NavCard from '../components/cards/NavCard.vue';
|
||||
import { ExportAllEntities, ImportAllEntities } from '../../bindings/app/internal/services/excelmodule';
|
||||
import { useErrorStore } from '../stores/error.store';
|
||||
|
||||
<!--<script setup lang="ts">-->
|
||||
<!--import { Button } from 'primevue';-->
|
||||
<!--import NavCard from '../components/cards/NavCard.vue';-->
|
||||
<!--import { ExportAllEntities, ImportAllEntities } from '../../bindings/app/internal/services/excelmodule';-->
|
||||
<!--import { useErrorStore } from '../stores/error.store';-->
|
||||
const errorStore = useErrorStore()
|
||||
|
||||
<!--const errorStore = useErrorStore()-->
|
||||
const importFromExcel = async () => {
|
||||
try {
|
||||
await ImportAllEntities()
|
||||
} catch(e) {
|
||||
errorStore.summon((e as Error).message)
|
||||
}
|
||||
}
|
||||
|
||||
<!--const importFromExcel = async () => {-->
|
||||
<!-- try {-->
|
||||
<!-- await ImportAllEntities()-->
|
||||
<!-- } catch(e) {-->
|
||||
<!-- errorStore.summon((e as Error).message)-->
|
||||
<!-- }-->
|
||||
<!--}-->
|
||||
|
||||
<!--const exportFromExcel = async () => {-->
|
||||
<!-- try {-->
|
||||
<!-- await ExportAllEntities()-->
|
||||
<!-- } catch(e) {-->
|
||||
<!-- errorStore.summon((e as Error).message)-->
|
||||
<!-- }-->
|
||||
<!--}-->
|
||||
<!--</script>-->
|
||||
|
||||
<!--<template>-->
|
||||
<!-- <div class="flex w-screen h-screen items-center gap-5 justify-center">-->
|
||||
<!-- <NavCard :title="'Пользователь'" :to="'/user'" :content="'Не может пользоваться туалетной бумагой'" />-->
|
||||
<!-- </div>-->
|
||||
<!-- <footer class="fixed w-full bottom-10 flex items-center justify-center gap-2">-->
|
||||
<!-- <Button severity="secondary" @click="importFromExcel">Импортировать данные</Button>-->
|
||||
<!-- <Button severity="secondary" @click="exportFromExcel">Экспортировать данные</Button>-->
|
||||
<!-- </footer>-->
|
||||
<!--</template>-->
|
||||
const exportFromExcel = async () => {
|
||||
try {
|
||||
await ExportAllEntities()
|
||||
} catch(e) {
|
||||
errorStore.summon((e as Error).message)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex w-screen h-screen items-center gap-5 justify-center">
|
||||
<NavCard :title="'Пользователь'" :to="'/user'" :content="'Не может пользоваться туалетной бумагой'" />
|
||||
</div>
|
||||
<footer class="fixed w-full bottom-10 flex items-center justify-center gap-2">
|
||||
<Button severity="secondary" @click="importFromExcel">Импортировать данные</Button>
|
||||
<Button severity="secondary" @click="exportFromExcel">Экспортировать данные</Button>
|
||||
</footer>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
3
frontend/src/pages/pages/GrebenPage.vue
Normal file
3
frontend/src/pages/pages/GrebenPage.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<h1>GREBEN</h1>
|
||||
</template>
|
||||
14
frontend/src/pages/pages/UserPage.vue
Normal file
14
frontend/src/pages/pages/UserPage.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { RouterView, useRoute, type RouteRecordRaw } from 'vue-router';
|
||||
import NavModal, { type Route } from '../../components/modals/NavModal.vue';
|
||||
import { routes } from '../../router/router';
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const lastRouteName = route.matched[route.matched.length - 2].path
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NavModal :routes="<Route[]>routes[routes.findIndex(r => r.path == lastRouteName)].children" />
|
||||
<RouterView />
|
||||
</template>
|
||||
7
frontend/src/pages/tables/PostTablePage.vue
Normal file
7
frontend/src/pages/tables/PostTablePage.vue
Normal file
@@ -0,0 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import PostScheme from '../../post/PostScheme.vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PostScheme />
|
||||
</template>
|
||||
148
frontend/src/post/PostScheme.vue
Normal file
148
frontend/src/post/PostScheme.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<script setup lang="ts">
|
||||
import Table from "../table/Table.vue";
|
||||
import { onMounted, reactive } from "vue";
|
||||
import { getDefaultValues } from "../utils/structs/defaults.util";
|
||||
import Service from "./post.service.ts";
|
||||
import type { Scheme } from "../types/scheme.type";
|
||||
import { Author, Post } from "../../bindings/app/internal/services";
|
||||
import { ref } from "vue";
|
||||
import type { Validate } from "../types/validate.type";
|
||||
|
||||
import AuthorService from "../author/author.service.ts";
|
||||
const authorService = new AuthorService();
|
||||
|
||||
import PosttypeService from "../posttype/posttype.service.ts";
|
||||
const posttypeService = new PosttypeService();
|
||||
|
||||
import CommentService from "../comment/comment.service.ts";
|
||||
import { SortedByOrder } from "../../bindings/app/internal/services/postservice.ts";
|
||||
import type { Search } from "../types/search.type.ts";
|
||||
|
||||
const commentService = new CommentService();
|
||||
|
||||
const service = new Service();
|
||||
|
||||
const items = ref<Post[]>([]);
|
||||
|
||||
const load = async () => {
|
||||
(scheme as any).Author.type!.nested!.values = await authorService.readAll();
|
||||
|
||||
(scheme as any).PostType.type!.nested!.values =
|
||||
await posttypeService.readAll();
|
||||
|
||||
(scheme as any).Comments.type!.nested!.values =
|
||||
await commentService.readAll();
|
||||
|
||||
items.value = await service.readAll();
|
||||
return items.value;
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await load();
|
||||
console.log(await SortedByOrder({ "Author": "DESC", "Text": "ASC" }));
|
||||
});
|
||||
|
||||
const scheme: Scheme<Post> = reactive({
|
||||
entityId: "PostId",
|
||||
|
||||
Id: {
|
||||
hidden: true,
|
||||
russian: 'Id',
|
||||
type: {
|
||||
primitive: "number",
|
||||
}
|
||||
},
|
||||
|
||||
Text: {
|
||||
russian: "Текст",
|
||||
type: {
|
||||
primitive: "string",
|
||||
},
|
||||
},
|
||||
|
||||
Deadline: {
|
||||
russian: "Дедлайн",
|
||||
date: true,
|
||||
type: {
|
||||
primitive: "date",
|
||||
},
|
||||
},
|
||||
|
||||
CreatedAt: {
|
||||
russian: "Дата создания",
|
||||
type: {
|
||||
primitive: "date",
|
||||
},
|
||||
},
|
||||
|
||||
AuthorId: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
},
|
||||
},
|
||||
|
||||
Author: {
|
||||
russian: "Автор",
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Name"],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
PostTypeId: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
},
|
||||
},
|
||||
|
||||
PostType: {
|
||||
russian: "Тип",
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Name"],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Comments: {
|
||||
russian: "Комментарии",
|
||||
many: true,
|
||||
type: {
|
||||
nested: {
|
||||
values: [],
|
||||
field: ["Text"],
|
||||
},
|
||||
},
|
||||
customWindow: {
|
||||
create: true,
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const getDefaults = () => {
|
||||
return ({ ...getDefaultValues(scheme), AuthorId: 1, PostTypeId: 1 });
|
||||
};
|
||||
|
||||
const validate: Validate<Post> = (entity) => {
|
||||
return {
|
||||
status: "success",
|
||||
};
|
||||
};
|
||||
|
||||
const search: Search<Post> = (input) => {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Table :scheme :service :get-defaults :load :items :validate @on-search="search">
|
||||
<template #CommentsCreate="{ data }">
|
||||
<p>{{ data }}</p>
|
||||
</template>
|
||||
</Table>
|
||||
</template>
|
||||
36
frontend/src/post/post.service.ts
Normal file
36
frontend/src/post/post.service.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import {
|
||||
GetAll,
|
||||
Create,
|
||||
Delete,
|
||||
GetById,
|
||||
Update,
|
||||
Count,
|
||||
} from "../../bindings/app/internal/services/postservice.ts";
|
||||
import type { Post } from "../../bindings/app/internal/services";
|
||||
import type { IService } from "../types/service.type.ts";
|
||||
|
||||
export default class PostService implements IService<Post> {
|
||||
async read(id: number) {
|
||||
return (await GetById(id)) as Post;
|
||||
}
|
||||
|
||||
async readAll() {
|
||||
return (await GetAll()) as Post[];
|
||||
}
|
||||
|
||||
async create(item: Post) {
|
||||
await Create(item);
|
||||
}
|
||||
|
||||
async delete(id: number) {
|
||||
return await Delete(id);
|
||||
}
|
||||
|
||||
async update(item: Post) {
|
||||
await Update(item);
|
||||
}
|
||||
|
||||
async count() {
|
||||
return await Count();
|
||||
}
|
||||
}
|
||||
62
frontend/src/posttype/PosttypeScheme.vue
Normal file
62
frontend/src/posttype/PosttypeScheme.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<script setup lang="ts">
|
||||
import Table from "../table/Table.vue";
|
||||
import { onMounted, reactive } from "vue";
|
||||
import { getDefaultValues } from "../utils/structs/defaults.util";
|
||||
import Service from "./posttype.service.ts";
|
||||
import type { Scheme } from "../types/scheme.type";
|
||||
import { PostType } from "../../bindings/app/internal/services";
|
||||
import { ref } from "vue";
|
||||
import type { Validate } from "../types/validate.type";
|
||||
|
||||
const service = new Service();
|
||||
|
||||
const items = ref<PostType[]>([]);
|
||||
|
||||
const load = async () => {
|
||||
items.value = await service.readAll();
|
||||
return items.value;
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await load();
|
||||
});
|
||||
|
||||
const scheme: Scheme<PostType> = reactive({
|
||||
entityId: "PostTypeId",
|
||||
|
||||
Id: {
|
||||
hidden: true,
|
||||
type: {
|
||||
primitive: "number",
|
||||
},
|
||||
},
|
||||
|
||||
Name: {
|
||||
russian: "Название",
|
||||
type: {
|
||||
primitive: "string",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const getDefaults = () => getDefaultValues(scheme);
|
||||
|
||||
const validate: Validate<PostType> = (entity) => {
|
||||
return {
|
||||
status: "success",
|
||||
};
|
||||
};
|
||||
|
||||
const colorize = (data: PostType): string => {
|
||||
if (data.Name === "test") {
|
||||
return "red";
|
||||
}
|
||||
return ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="w-screen h-screen">
|
||||
<Table :scheme :service :get-defaults :load :items :validate :colorize></Table>
|
||||
</main>
|
||||
</template>
|
||||
36
frontend/src/posttype/posttype.service.ts
Normal file
36
frontend/src/posttype/posttype.service.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import {
|
||||
GetAll,
|
||||
Create,
|
||||
Delete,
|
||||
GetById,
|
||||
Update,
|
||||
Count,
|
||||
} from "../../bindings/app/internal/services/posttypeservice.ts";
|
||||
import type { PostType } from "../../bindings/app/internal/services";
|
||||
import type { IService } from "../types/service.type.ts";
|
||||
|
||||
export default class PostTypeService implements IService<PostType> {
|
||||
async read(id: number) {
|
||||
return (await GetById(id)) as PostType;
|
||||
}
|
||||
|
||||
async readAll() {
|
||||
return (await GetAll()) as PostType[];
|
||||
}
|
||||
|
||||
async create(item: PostType) {
|
||||
await Create(item);
|
||||
}
|
||||
|
||||
async delete(id: number) {
|
||||
return await Delete(id);
|
||||
}
|
||||
|
||||
async update(item: PostType) {
|
||||
await Update(item);
|
||||
}
|
||||
|
||||
async count() {
|
||||
return await Count();
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,32 @@
|
||||
import { createRouter, createWebHistory, type RouteRecordRaw } from "vue-router";
|
||||
import Index from "../pages/Index.vue";
|
||||
|
||||
import UserPage from "../pages/pages/UserPage.vue";
|
||||
import PostTablePage from "../pages/tables/PostTablePage.vue";
|
||||
import GrebenPage from "../pages/pages/GrebenPage.vue";
|
||||
|
||||
export const routes: RouteRecordRaw[] = [{
|
||||
path: "/",
|
||||
component: Index,
|
||||
name: 'Главная'
|
||||
}, ] as const
|
||||
}, {
|
||||
path: '/user',
|
||||
name: 'Пользователь',
|
||||
component: UserPage,
|
||||
redirect: '/user/post',
|
||||
children: [
|
||||
{
|
||||
component: PostTablePage,
|
||||
path: '/user/post',
|
||||
name: 'Новости'
|
||||
}, {
|
||||
component: GrebenPage,
|
||||
path: '/user/greben',
|
||||
name: 'Страница гребня'
|
||||
}
|
||||
]
|
||||
}] as const
|
||||
|
||||
export const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
});
|
||||
|
||||
// {
|
||||
// path: '/user',
|
||||
// name: 'Пользователь',
|
||||
// component: UserPage,
|
||||
// redirect: '/user/post',
|
||||
// children: [
|
||||
// {
|
||||
// component: PostTablePage,
|
||||
// path: '/user/post',
|
||||
// name: 'Новости'
|
||||
// }, {
|
||||
// component: GrebenPage,
|
||||
// path: '/user/greben',
|
||||
// name: 'Страница гребня'
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
@@ -5,25 +5,10 @@
|
||||
|
||||
html, body, .background {
|
||||
background: white;
|
||||
color: rgb(51, 65, 85);
|
||||
}
|
||||
|
||||
.secondary-background {
|
||||
background: var(--p-content-background)
|
||||
}
|
||||
|
||||
.native-border {
|
||||
border: 1px solid var(--p-select-border-color);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
html, body, .background {
|
||||
background: #121212;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.native-border {
|
||||
border: 1px solid rgb(100, 100, 109);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -62,7 +62,7 @@ async function handleSave() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog v-model:visible="showCreate" class="w-[500px]">
|
||||
<Dialog v-model:visible="showCreate">
|
||||
<template #header>
|
||||
<h1>{{ props.updateMode ? 'Изменить' : 'Создать' }} {{ props.name?.toLowerCase() }}</h1>
|
||||
</template>
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
<script setup lang="ts" generic="T extends IEntity">
|
||||
import type {IEntity} from "../types/entity.type.ts";
|
||||
import type {SortOptions} from "../types/sort-options.type.ts";
|
||||
import type {Scheme} from "../types/scheme.type.ts";
|
||||
import {Select} from 'primevue'
|
||||
import {watch} from "vue";
|
||||
|
||||
|
||||
const options = defineModel<SortOptions<T>>()
|
||||
const optionsKeys = Object.keys(options.value as T) as (keyof T)[]
|
||||
|
||||
defineProps<{
|
||||
scheme: Scheme<T>
|
||||
load: () => Promise<T[]>
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ul class="flex flex-col gap-2 native-border secondary-background p-3 rounded-md">
|
||||
<li v-for="optionKey in optionsKeys" class="flex items-center justify-between w-full">
|
||||
<h1>{{ scheme[optionKey].russian }}</h1>
|
||||
<Select size="small" class="w-24" :options="['NONE', 'ASC', 'DESC']" v-model="options![optionKey]" @value-change="load">
|
||||
<template #value="{ value }">
|
||||
<span class="pi pi-sort-amount-up-alt" v-if="value == 'ASC'"></span>
|
||||
<span class="pi pi-sort-amount-down" v-else-if="value == 'DESC'"></span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</Select>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
@@ -1,18 +1,20 @@
|
||||
<script setup lang="ts" generic="T extends IEntity">
|
||||
import {onMounted, ref, watch, type UnwrapRef} from "vue";
|
||||
import type {TableProps} from "../types/table-props.type";
|
||||
import {DataTable, Column, Button, InputText} from "primevue";
|
||||
import {manyStructsView} from "../utils/structs/structs-view.util";
|
||||
import type {TableEmits} from "../types/table-emits.type";
|
||||
import { onMounted, ref, watch, type UnwrapRef } from "vue";
|
||||
import type { TableProps } from "../types/table-props.type";
|
||||
import { DataTable, Column, Button, InputText } from "primevue";
|
||||
import { manyStructsView } from "../utils/structs/structs-view.util";
|
||||
import type { TableEmits } from "../types/table-emits.type";
|
||||
import FloatingButton from "../components/buttons/FloatingButton.vue";
|
||||
import type {IEntity} from "../types/entity.type";
|
||||
import type { IEntity } from "../types/entity.type";
|
||||
import DialogWindow from "./DialogWindow.vue";
|
||||
import {viewDate} from "../utils/date/view.util";
|
||||
import SortingOptions from "./SortingOptions.vue";
|
||||
import type {SortOptions} from "../types/sort-options.type.ts";
|
||||
import { viewDate } from "../utils/date/view.util";
|
||||
|
||||
const props = defineProps<TableProps<T>>();
|
||||
|
||||
onMounted(async () => {
|
||||
props.load();
|
||||
});
|
||||
|
||||
type Key = keyof T;
|
||||
const keys = Object.keys(props.scheme) as Key[];
|
||||
const emits = defineEmits<TableEmits>();
|
||||
@@ -54,8 +56,8 @@ watch(createItem, (value) => {
|
||||
});
|
||||
|
||||
const handleFloatingButtonClick = () => {
|
||||
emits('onCreateOpen')
|
||||
emits('onOpen')
|
||||
emits("onCreateOpen");
|
||||
emits("onOpen");
|
||||
showCreate.value = true;
|
||||
};
|
||||
const slots = defineSlots();
|
||||
@@ -63,60 +65,70 @@ const slots = defineSlots();
|
||||
const createSlotName = (key: any) => key + "Create";
|
||||
const updateSlotName = (key: any) => key + "Update";
|
||||
|
||||
watch(() => props.items, () => {
|
||||
watch(
|
||||
() => props.items,
|
||||
() => {
|
||||
if (props.colorize) {
|
||||
const trs = document.querySelectorAll("tr");
|
||||
props.items.forEach(item => {
|
||||
props.items.forEach((item) => {
|
||||
const tr = trs[item.Id];
|
||||
if (tr) {
|
||||
tr.style.backgroundColor = props.colorize!(item);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
const input = ref('')
|
||||
const sortOptions = defineModel<SortOptions<T>>('sort-options');
|
||||
const showSortOptions = ref(false)
|
||||
},
|
||||
);
|
||||
|
||||
const input = defineModel<string>("search", { default: "" });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="m-2 flex flex-col items-center gap-2">
|
||||
<div class="flex flex-col gap-2 relative">
|
||||
<div class="flex items-center justify-center gap-2 h-10">
|
||||
<Button severity="secondary" class="h-full aspect-square" @click="showSortOptions = !showSortOptions">
|
||||
<span class="pi pi-sort"></span>
|
||||
</Button>
|
||||
|
||||
<InputText class="h-full w-64" v-model="input"/>
|
||||
<Button severity="secondary" class="h-full aspect-square" @click="emits('onSearch', input)">
|
||||
<div class="flex h-10 justify-center m-4 gap-2">
|
||||
<InputText v-model="input" placeholder="Поиск" class="h-full w-64" />
|
||||
<Button class="h-full aspect-square" severity="secondary">
|
||||
<span class="pi pi-search"></span>
|
||||
</Button>
|
||||
</div>
|
||||
<SortingOptions v-model="sortOptions as SortOptions<T>" :scheme v-if="showSortOptions"
|
||||
class="absolute z-10 w-full top-full translate-y-2" :load="props.load"></SortingOptions>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<DialogWindow :name :load :items :validate :scheme :service :get-defaults v-model:item="<T>createItem"
|
||||
v-model:show="showCreate" @on-save="data => emits('onSave', data)"
|
||||
@on-save-create="data => emits('onSaveCreate', data)">
|
||||
<DialogWindow
|
||||
:name
|
||||
:load
|
||||
:items
|
||||
:validate
|
||||
:scheme
|
||||
:service
|
||||
:get-defaults
|
||||
v-model:item="<T>createItem"
|
||||
v-model:show="showCreate"
|
||||
@on-save="(data) => emits('onSave', data)"
|
||||
@on-save-create="(data) => emits('onSaveCreate', data)"
|
||||
>
|
||||
<template v-for="key in keys" #[key]="{ data }">
|
||||
<slot :name="<string>key" :data="data"></slot>
|
||||
<slot :name="<string>key" :data></slot>
|
||||
</template>
|
||||
<template v-for="key in keys" #[createSlotName(key)]="{ data }">
|
||||
<slot :name="createSlotName(key)" :data="data"></slot>
|
||||
<slot :name="createSlotName(key)" :data></slot>
|
||||
</template>
|
||||
</DialogWindow>
|
||||
<DialogWindow :name :load :items :validate :scheme update-mode :service :get-defaults v-model:item="<T>updateItem"
|
||||
v-model:show="showUpdate" @on-save="data => emits('onSave', data)"
|
||||
@on-save-update="data => emits('onSaveUpdate', data)">
|
||||
<DialogWindow
|
||||
:name
|
||||
:load
|
||||
:items
|
||||
:validate
|
||||
:scheme
|
||||
update-mode
|
||||
:service
|
||||
:get-defaults
|
||||
v-model:item="<T>updateItem"
|
||||
v-model:show="showUpdate"
|
||||
@on-save="(data) => emits('onSave', data)"
|
||||
@on-save-update="(data) => emits('onSaveUpdate', data)"
|
||||
>
|
||||
<template v-for="key in keys" #[key]="{ data }">
|
||||
<slot :name="<string>key" :data="data"></slot>
|
||||
<slot :name="<string>key" :data></slot>
|
||||
</template>
|
||||
<template v-for="key in keys" #[updateSlotName(key)]="{ data }">
|
||||
<slot :name="updateSlotName(key)" :data="data"></slot>
|
||||
<slot :name="updateSlotName(key)" :data></slot>
|
||||
</template>
|
||||
</DialogWindow>
|
||||
<div>
|
||||
@@ -125,17 +137,31 @@ const showSortOptions = ref(false)
|
||||
<p>{{ props.name }}</p>
|
||||
</template>
|
||||
<template v-for="key in keys">
|
||||
<Column :header="props.scheme[key]?.russian" v-if="!props.scheme[key].hidden">
|
||||
<Column
|
||||
:header="props.scheme[key]?.russian"
|
||||
v-if="!props.scheme[key].hidden"
|
||||
>
|
||||
<template #body="{ data }">
|
||||
<p class="truncate max-w-56" v-tooltip="viewDate(manyStructsView(
|
||||
<p
|
||||
class="truncate max-w-56"
|
||||
v-tooltip="
|
||||
viewDate(
|
||||
manyStructsView(
|
||||
data[key],
|
||||
props.scheme[key]?.type?.nested?.field,
|
||||
), scheme[key]?.type?.primitive)">
|
||||
),
|
||||
scheme[key]?.type?.primitive,
|
||||
)
|
||||
"
|
||||
>
|
||||
{{
|
||||
viewDate(manyStructsView(
|
||||
viewDate(
|
||||
manyStructsView(
|
||||
data[key],
|
||||
props.scheme[key]?.type?.nested?.field,
|
||||
), scheme[key]?.type?.primitive)
|
||||
),
|
||||
scheme[key]?.type?.primitive,
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
</template>
|
||||
@@ -144,28 +170,32 @@ const showSortOptions = ref(false)
|
||||
<Column header="Действия">
|
||||
<template #body="{ data }">
|
||||
<div class="flex gap-2">
|
||||
<Button severity="secondary" icon="pi pi-pencil" @click="async () => {
|
||||
await emits('onUpdateOpen')
|
||||
await emits('onOpen')
|
||||
updateItem = data
|
||||
}"></Button>
|
||||
<Button severity="danger" icon="pi pi-trash" @click="async () => {
|
||||
await emits('onDelete', data)
|
||||
await props.service.delete(data.Id)
|
||||
await load()
|
||||
}"></Button>
|
||||
<Button
|
||||
severity="secondary"
|
||||
icon="pi pi-pencil"
|
||||
@click="
|
||||
async () => {
|
||||
await emits('onUpdateOpen');
|
||||
await emits('onOpen');
|
||||
updateItem = data;
|
||||
}
|
||||
"
|
||||
></Button>
|
||||
<Button
|
||||
severity="danger"
|
||||
icon="pi pi-trash"
|
||||
@click="
|
||||
async () => {
|
||||
await emits('onDelete', data);
|
||||
await props.service.delete(data.Id);
|
||||
await load();
|
||||
}
|
||||
"
|
||||
></Button>
|
||||
</div>
|
||||
</template>
|
||||
</Column>
|
||||
<template #paginatorstart>
|
||||
<Button severity="secondary" @click="props.load">
|
||||
<span class="pi pi-refresh"></span>
|
||||
</Button>
|
||||
</template>
|
||||
<template #paginatorend>
|
||||
<span></span>
|
||||
</template>
|
||||
</DataTable>
|
||||
<FloatingButton @click="handleFloatingButtonClick"/>
|
||||
<FloatingButton @click="handleFloatingButtonClick" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
3
frontend/src/types/search.type.ts
Normal file
3
frontend/src/types/search.type.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { IEntity } from "./entity.type";
|
||||
|
||||
export type Search<T extends IEntity> = (input: string) => T[]
|
||||
@@ -1,6 +0,0 @@
|
||||
import type { IEntity } from "./entity.type";
|
||||
import type { Sorting } from "./sorting.type";
|
||||
|
||||
export type SortOptions<T extends IEntity> = {
|
||||
[key in keyof Partial<T>]: Sorting
|
||||
}
|
||||
7
frontend/src/types/sort.type.ts
Normal file
7
frontend/src/types/sort.type.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { IEntity } from "./entity.type";
|
||||
|
||||
export type SortOptions<T extends IEntity> = {
|
||||
[key in keyof T]: "ASC" | "DESC"
|
||||
}
|
||||
|
||||
export type Sort<T extends IEntity> = (options: SortOptions<T>) => T[]
|
||||
@@ -1 +0,0 @@
|
||||
export type Sorting = "DESC" | "ASC" | "NONE"
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { IEntity } from "./entity.type";
|
||||
import type { Scheme } from "./scheme.type";
|
||||
import type { Search } from "./search.type";
|
||||
import type { IService } from "./service.type";
|
||||
import type { Sort } from "./sort.type";
|
||||
import type { Validate } from "./validate.type";
|
||||
|
||||
export interface TableProps<T extends IEntity> {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import type { IEntity } from "../../types/entity.type";
|
||||
import type { Scheme } from "../../types/scheme.type";
|
||||
import type { SortOptions } from "../../types/sort-options.type";
|
||||
|
||||
export const getDefaultSortOptions = <T extends IEntity>(scheme: Scheme<T>): SortOptions<T> => {
|
||||
const keys = Object.keys(scheme) as (keyof T)[]
|
||||
const result: Partial<SortOptions<T>> = {}
|
||||
|
||||
keys.forEach(key => {
|
||||
if (!scheme[key].hidden && key !== 'entityId' && !scheme[key].many) {
|
||||
result[key] = 'NONE'
|
||||
}
|
||||
})
|
||||
|
||||
return result as SortOptions<T>
|
||||
}
|
||||
6
frontend/src/utils/structs/default-sort.util.ts
Normal file
6
frontend/src/utils/structs/default-sort.util.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { IEntity } from "../../types/entity.type";
|
||||
import type { Scheme } from "../../types/scheme.type";
|
||||
|
||||
export const defaultSort = <T extends IEntity>(scheme: Scheme<T>) => {
|
||||
|
||||
}
|
||||
12
go.mod
12
go.mod
@@ -1,4 +1,4 @@
|
||||
module git.gogacoder.ru/NTO/boilerplate
|
||||
module app
|
||||
|
||||
go 1.23.0
|
||||
|
||||
@@ -6,8 +6,6 @@ toolchain go1.24.1
|
||||
|
||||
require (
|
||||
github.com/kuzgoga/fogg v0.1.2
|
||||
github.com/ncruces/go-sqlite3 v0.24.1
|
||||
github.com/ncruces/go-sqlite3/gormlite v0.24.0
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.9
|
||||
github.com/xuri/excelize/v2 v2.9.0
|
||||
golang.org/x/text v0.23.0
|
||||
@@ -46,9 +44,8 @@ require (
|
||||
github.com/lmittmann/tint v1.0.4 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.24 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/ncruces/julianday v1.0.0 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
||||
github.com/richardlehane/mscfb v1.0.4 // indirect
|
||||
@@ -57,18 +54,17 @@ require (
|
||||
github.com/samber/lo v1.38.1 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||
github.com/skeema/knownhosts v1.2.2 // indirect
|
||||
github.com/tetratelabs/wazero v1.9.0 // indirect
|
||||
github.com/wailsapp/go-webview2 v1.0.19 // indirect
|
||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
|
||||
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/crypto v0.30.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/net v0.32.0 // indirect
|
||||
golang.org/x/sync v0.12.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/tools v0.28.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
|
||||
24
go.sum
24
go.sum
@@ -99,18 +99,12 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
|
||||
github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/ncruces/go-sqlite3 v0.24.1 h1:qHlIz+dlH3Y0wCUErFZXon5hCvw1Kc9eEkZVYYi8p14=
|
||||
github.com/ncruces/go-sqlite3 v0.24.1/go.mod h1:n6Z7036yFilJx04yV0mi5JWaF66rUmXn1It9Ux8dx68=
|
||||
github.com/ncruces/go-sqlite3/gormlite v0.24.0 h1:81sHeq3CCdhjoqAB650n5wEdRlLO9VBvosArskcN3+c=
|
||||
github.com/ncruces/go-sqlite3/gormlite v0.24.0/go.mod h1:vXfVWdBfg7qOgqQqHpzUWl9LLswD0h+8mK4oouaV2oc=
|
||||
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
|
||||
github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
|
||||
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
||||
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
|
||||
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||
@@ -143,8 +137,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
|
||||
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
|
||||
github.com/wailsapp/go-webview2 v1.0.19 h1:7U3QcDj1PrBPaxJNCui2k1SkWml+Q5kvFUFyTImA6NU=
|
||||
github.com/wailsapp/go-webview2 v1.0.19/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
|
||||
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
||||
@@ -165,8 +157,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
|
||||
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s=
|
||||
@@ -207,15 +199,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
|
||||
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package excel
|
||||
|
||||
import (
|
||||
"app/internal/dialogs"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/dialogs"
|
||||
"github.com/kuzgoga/fogg"
|
||||
"github.com/xuri/excelize/v2"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
615
internal/dal/authors.gen.go
Normal file
615
internal/dal/authors.gen.go
Normal file
@@ -0,0 +1,615 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package dal
|
||||
|
||||
import (
|
||||
"app/internal/models"
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
)
|
||||
|
||||
func newAuthor(db *gorm.DB, opts ...gen.DOOption) author {
|
||||
_author := author{}
|
||||
|
||||
_author.authorDo.UseDB(db, opts...)
|
||||
_author.authorDo.UseModel(&models.Author{})
|
||||
|
||||
tableName := _author.authorDo.TableName()
|
||||
_author.ALL = field.NewAsterisk(tableName)
|
||||
_author.Id = field.NewUint(tableName, "id")
|
||||
_author.Name = field.NewString(tableName, "name")
|
||||
_author.Posts = authorHasManyPosts{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Posts", "models.Post"),
|
||||
Author: struct {
|
||||
field.RelationField
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
}
|
||||
Comments struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Posts.Author", "models.Author"),
|
||||
Posts: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Posts.Author.Posts", "models.Post"),
|
||||
},
|
||||
Comments: struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Posts.Author.Comments", "models.Comment"),
|
||||
Author: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Posts.Author.Comments.Author", "models.Author"),
|
||||
},
|
||||
Posts: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Posts.Author.Comments.Posts", "models.Post"),
|
||||
},
|
||||
},
|
||||
},
|
||||
PostType: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Posts.PostType", "models.PostType"),
|
||||
},
|
||||
Comments: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Posts.Comments", "models.Comment"),
|
||||
},
|
||||
}
|
||||
|
||||
_author.Comments = authorHasManyComments{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Comments", "models.Comment"),
|
||||
}
|
||||
|
||||
_author.fillFieldMap()
|
||||
|
||||
return _author
|
||||
}
|
||||
|
||||
type author struct {
|
||||
authorDo
|
||||
|
||||
ALL field.Asterisk
|
||||
Id field.Uint
|
||||
Name field.String
|
||||
Posts authorHasManyPosts
|
||||
|
||||
Comments authorHasManyComments
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (a author) Table(newTableName string) *author {
|
||||
a.authorDo.UseTable(newTableName)
|
||||
return a.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (a author) As(alias string) *author {
|
||||
a.authorDo.DO = *(a.authorDo.As(alias).(*gen.DO))
|
||||
return a.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (a *author) updateTableName(table string) *author {
|
||||
a.ALL = field.NewAsterisk(table)
|
||||
a.Id = field.NewUint(table, "id")
|
||||
a.Name = field.NewString(table, "name")
|
||||
|
||||
a.fillFieldMap()
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *author) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := a.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (a *author) fillFieldMap() {
|
||||
a.fieldMap = make(map[string]field.Expr, 4)
|
||||
a.fieldMap["id"] = a.Id
|
||||
a.fieldMap["name"] = a.Name
|
||||
|
||||
}
|
||||
|
||||
func (a author) clone(db *gorm.DB) author {
|
||||
a.authorDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return a
|
||||
}
|
||||
|
||||
func (a author) replaceDB(db *gorm.DB) author {
|
||||
a.authorDo.ReplaceDB(db)
|
||||
return a
|
||||
}
|
||||
|
||||
type authorHasManyPosts struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
|
||||
Author struct {
|
||||
field.RelationField
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
}
|
||||
Comments struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
}
|
||||
PostType struct {
|
||||
field.RelationField
|
||||
}
|
||||
Comments struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
|
||||
func (a authorHasManyPosts) Where(conds ...field.Expr) *authorHasManyPosts {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authorHasManyPosts) WithContext(ctx context.Context) *authorHasManyPosts {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authorHasManyPosts) Session(session *gorm.Session) *authorHasManyPosts {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authorHasManyPosts) Model(m *models.Author) *authorHasManyPostsTx {
|
||||
return &authorHasManyPostsTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
type authorHasManyPostsTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a authorHasManyPostsTx) Find() (result []*models.Post, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a authorHasManyPostsTx) Append(values ...*models.Post) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a authorHasManyPostsTx) Replace(values ...*models.Post) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a authorHasManyPostsTx) Delete(values ...*models.Post) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a authorHasManyPostsTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a authorHasManyPostsTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
type authorHasManyComments struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
}
|
||||
|
||||
func (a authorHasManyComments) Where(conds ...field.Expr) *authorHasManyComments {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authorHasManyComments) WithContext(ctx context.Context) *authorHasManyComments {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authorHasManyComments) Session(session *gorm.Session) *authorHasManyComments {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authorHasManyComments) Model(m *models.Author) *authorHasManyCommentsTx {
|
||||
return &authorHasManyCommentsTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
type authorHasManyCommentsTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a authorHasManyCommentsTx) Find() (result []*models.Comment, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a authorHasManyCommentsTx) Append(values ...*models.Comment) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a authorHasManyCommentsTx) Replace(values ...*models.Comment) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a authorHasManyCommentsTx) Delete(values ...*models.Comment) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a authorHasManyCommentsTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a authorHasManyCommentsTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
type authorDo struct{ gen.DO }
|
||||
|
||||
type IAuthorDo interface {
|
||||
gen.SubQuery
|
||||
Debug() IAuthorDo
|
||||
WithContext(ctx context.Context) IAuthorDo
|
||||
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||
ReplaceDB(db *gorm.DB)
|
||||
ReadDB() IAuthorDo
|
||||
WriteDB() IAuthorDo
|
||||
As(alias string) gen.Dao
|
||||
Session(config *gorm.Session) IAuthorDo
|
||||
Columns(cols ...field.Expr) gen.Columns
|
||||
Clauses(conds ...clause.Expression) IAuthorDo
|
||||
Not(conds ...gen.Condition) IAuthorDo
|
||||
Or(conds ...gen.Condition) IAuthorDo
|
||||
Select(conds ...field.Expr) IAuthorDo
|
||||
Where(conds ...gen.Condition) IAuthorDo
|
||||
Order(conds ...field.Expr) IAuthorDo
|
||||
Distinct(cols ...field.Expr) IAuthorDo
|
||||
Omit(cols ...field.Expr) IAuthorDo
|
||||
Join(table schema.Tabler, on ...field.Expr) IAuthorDo
|
||||
LeftJoin(table schema.Tabler, on ...field.Expr) IAuthorDo
|
||||
RightJoin(table schema.Tabler, on ...field.Expr) IAuthorDo
|
||||
Group(cols ...field.Expr) IAuthorDo
|
||||
Having(conds ...gen.Condition) IAuthorDo
|
||||
Limit(limit int) IAuthorDo
|
||||
Offset(offset int) IAuthorDo
|
||||
Count() (count int64, err error)
|
||||
Scopes(funcs ...func(gen.Dao) gen.Dao) IAuthorDo
|
||||
Unscoped() IAuthorDo
|
||||
Create(values ...*models.Author) error
|
||||
CreateInBatches(values []*models.Author, batchSize int) error
|
||||
Save(values ...*models.Author) error
|
||||
First() (*models.Author, error)
|
||||
Take() (*models.Author, error)
|
||||
Last() (*models.Author, error)
|
||||
Find() ([]*models.Author, error)
|
||||
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Author, err error)
|
||||
FindInBatches(result *[]*models.Author, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||
Pluck(column field.Expr, dest interface{}) error
|
||||
Delete(...*models.Author) (info gen.ResultInfo, err error)
|
||||
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||
Attrs(attrs ...field.AssignExpr) IAuthorDo
|
||||
Assign(attrs ...field.AssignExpr) IAuthorDo
|
||||
Joins(fields ...field.RelationField) IAuthorDo
|
||||
Preload(fields ...field.RelationField) IAuthorDo
|
||||
FirstOrInit() (*models.Author, error)
|
||||
FirstOrCreate() (*models.Author, error)
|
||||
FindByPage(offset int, limit int) (result []*models.Author, count int64, err error)
|
||||
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||
Scan(result interface{}) (err error)
|
||||
Returning(value interface{}, columns ...string) IAuthorDo
|
||||
UnderlyingDB() *gorm.DB
|
||||
schema.Tabler
|
||||
}
|
||||
|
||||
func (a authorDo) Debug() IAuthorDo {
|
||||
return a.withDO(a.DO.Debug())
|
||||
}
|
||||
|
||||
func (a authorDo) WithContext(ctx context.Context) IAuthorDo {
|
||||
return a.withDO(a.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (a authorDo) ReadDB() IAuthorDo {
|
||||
return a.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (a authorDo) WriteDB() IAuthorDo {
|
||||
return a.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (a authorDo) Session(config *gorm.Session) IAuthorDo {
|
||||
return a.withDO(a.DO.Session(config))
|
||||
}
|
||||
|
||||
func (a authorDo) Clauses(conds ...clause.Expression) IAuthorDo {
|
||||
return a.withDO(a.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (a authorDo) Returning(value interface{}, columns ...string) IAuthorDo {
|
||||
return a.withDO(a.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (a authorDo) Not(conds ...gen.Condition) IAuthorDo {
|
||||
return a.withDO(a.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (a authorDo) Or(conds ...gen.Condition) IAuthorDo {
|
||||
return a.withDO(a.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (a authorDo) Select(conds ...field.Expr) IAuthorDo {
|
||||
return a.withDO(a.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (a authorDo) Where(conds ...gen.Condition) IAuthorDo {
|
||||
return a.withDO(a.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (a authorDo) Order(conds ...field.Expr) IAuthorDo {
|
||||
return a.withDO(a.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (a authorDo) Distinct(cols ...field.Expr) IAuthorDo {
|
||||
return a.withDO(a.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (a authorDo) Omit(cols ...field.Expr) IAuthorDo {
|
||||
return a.withDO(a.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (a authorDo) Join(table schema.Tabler, on ...field.Expr) IAuthorDo {
|
||||
return a.withDO(a.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (a authorDo) LeftJoin(table schema.Tabler, on ...field.Expr) IAuthorDo {
|
||||
return a.withDO(a.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a authorDo) RightJoin(table schema.Tabler, on ...field.Expr) IAuthorDo {
|
||||
return a.withDO(a.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (a authorDo) Group(cols ...field.Expr) IAuthorDo {
|
||||
return a.withDO(a.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (a authorDo) Having(conds ...gen.Condition) IAuthorDo {
|
||||
return a.withDO(a.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (a authorDo) Limit(limit int) IAuthorDo {
|
||||
return a.withDO(a.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (a authorDo) Offset(offset int) IAuthorDo {
|
||||
return a.withDO(a.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (a authorDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IAuthorDo {
|
||||
return a.withDO(a.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (a authorDo) Unscoped() IAuthorDo {
|
||||
return a.withDO(a.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (a authorDo) Create(values ...*models.Author) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Create(values)
|
||||
}
|
||||
|
||||
func (a authorDo) CreateInBatches(values []*models.Author, batchSize int) error {
|
||||
return a.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (a authorDo) Save(values ...*models.Author) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return a.DO.Save(values)
|
||||
}
|
||||
|
||||
func (a authorDo) First() (*models.Author, error) {
|
||||
if result, err := a.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.Author), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authorDo) Take() (*models.Author, error) {
|
||||
if result, err := a.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.Author), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authorDo) Last() (*models.Author, error) {
|
||||
if result, err := a.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.Author), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authorDo) Find() ([]*models.Author, error) {
|
||||
result, err := a.DO.Find()
|
||||
return result.([]*models.Author), err
|
||||
}
|
||||
|
||||
func (a authorDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Author, err error) {
|
||||
buf := make([]*models.Author, 0, batchSize)
|
||||
err = a.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (a authorDo) FindInBatches(result *[]*models.Author, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return a.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (a authorDo) Attrs(attrs ...field.AssignExpr) IAuthorDo {
|
||||
return a.withDO(a.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (a authorDo) Assign(attrs ...field.AssignExpr) IAuthorDo {
|
||||
return a.withDO(a.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (a authorDo) Joins(fields ...field.RelationField) IAuthorDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Joins(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authorDo) Preload(fields ...field.RelationField) IAuthorDo {
|
||||
for _, _f := range fields {
|
||||
a = *a.withDO(a.DO.Preload(_f))
|
||||
}
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a authorDo) FirstOrInit() (*models.Author, error) {
|
||||
if result, err := a.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.Author), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authorDo) FirstOrCreate() (*models.Author, error) {
|
||||
if result, err := a.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.Author), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a authorDo) FindByPage(offset int, limit int) (result []*models.Author, count int64, err error) {
|
||||
result, err = a.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = a.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (a authorDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = a.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = a.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (a authorDo) Scan(result interface{}) (err error) {
|
||||
return a.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (a authorDo) Delete(models ...*models.Author) (result gen.ResultInfo, err error) {
|
||||
return a.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (a *authorDo) withDO(do gen.Dao) *authorDo {
|
||||
a.DO = *do.(*gen.DO)
|
||||
return a
|
||||
}
|
||||
145
internal/dal/authors.gen_test.go
Normal file
145
internal/dal/authors.gen_test.go
Normal file
@@ -0,0 +1,145 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package dal
|
||||
|
||||
import (
|
||||
"app/internal/models"
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
func init() {
|
||||
InitializeDB()
|
||||
err := _gen_test_db.AutoMigrate(&models.Author{})
|
||||
if err != nil {
|
||||
fmt.Printf("Error: AutoMigrate(&models.Author{}) fail: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_authorQuery(t *testing.T) {
|
||||
author := newAuthor(_gen_test_db)
|
||||
author = *author.As(author.TableName())
|
||||
_do := author.WithContext(context.Background()).Debug()
|
||||
|
||||
primaryKey := field.NewString(author.TableName(), clause.PrimaryKey)
|
||||
_, err := _do.Unscoped().Where(primaryKey.IsNotNull()).Delete()
|
||||
if err != nil {
|
||||
t.Error("clean table <authors> fail:", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, ok := author.GetFieldByName("")
|
||||
if ok {
|
||||
t.Error("GetFieldByName(\"\") from author success")
|
||||
}
|
||||
|
||||
err = _do.Create(&models.Author{})
|
||||
if err != nil {
|
||||
t.Error("create item in table <authors> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.Save(&models.Author{})
|
||||
if err != nil {
|
||||
t.Error("create item in table <authors> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.CreateInBatches([]*models.Author{{}, {}}, 10)
|
||||
if err != nil {
|
||||
t.Error("create item in table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Select(author.ALL).Take()
|
||||
if err != nil {
|
||||
t.Error("Take() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.First()
|
||||
if err != nil {
|
||||
t.Error("First() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Last()
|
||||
if err != nil {
|
||||
t.Error("First() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil })
|
||||
if err != nil {
|
||||
t.Error("FindInBatch() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*models.Author{}, 10, func(tx gen.Dao, batch int) error { return nil })
|
||||
if err != nil {
|
||||
t.Error("FindInBatches() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Select(author.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find()
|
||||
if err != nil {
|
||||
t.Error("Find() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Distinct(primaryKey).Take()
|
||||
if err != nil {
|
||||
t.Error("select Distinct() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Select(author.ALL).Omit(primaryKey).Take()
|
||||
if err != nil {
|
||||
t.Error("Omit() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Group(primaryKey).Find()
|
||||
if err != nil {
|
||||
t.Error("Group() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find()
|
||||
if err != nil {
|
||||
t.Error("Scopes() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, _, err = _do.FindByPage(0, 1)
|
||||
if err != nil {
|
||||
t.Error("FindByPage() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.ScanByPage(&models.Author{}, 0, 1)
|
||||
if err != nil {
|
||||
t.Error("ScanByPage() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit()
|
||||
if err != nil {
|
||||
t.Error("FirstOrInit() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate()
|
||||
if err != nil {
|
||||
t.Error("FirstOrCreate() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
var _a _another
|
||||
var _aPK = field.NewString(_a.TableName(), "id")
|
||||
|
||||
err = _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{})
|
||||
if err != nil {
|
||||
t.Error("Join() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{})
|
||||
if err != nil {
|
||||
t.Error("LeftJoin() on table <authors> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Not().Or().Clauses().Take()
|
||||
if err != nil {
|
||||
t.Error("Not/Or/Clauses on table <authors> fail:", err)
|
||||
}
|
||||
}
|
||||
622
internal/dal/comments.gen.go
Normal file
622
internal/dal/comments.gen.go
Normal file
@@ -0,0 +1,622 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package dal
|
||||
|
||||
import (
|
||||
"app/internal/models"
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
)
|
||||
|
||||
func newComment(db *gorm.DB, opts ...gen.DOOption) comment {
|
||||
_comment := comment{}
|
||||
|
||||
_comment.commentDo.UseDB(db, opts...)
|
||||
_comment.commentDo.UseModel(&models.Comment{})
|
||||
|
||||
tableName := _comment.commentDo.TableName()
|
||||
_comment.ALL = field.NewAsterisk(tableName)
|
||||
_comment.Id = field.NewUint(tableName, "id")
|
||||
_comment.Text = field.NewString(tableName, "text")
|
||||
_comment.AuthorId = field.NewUint(tableName, "author_id")
|
||||
_comment.Author = commentBelongsToAuthor{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Author", "models.Author"),
|
||||
Posts: struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
PostType struct {
|
||||
field.RelationField
|
||||
}
|
||||
Comments struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts", "models.Post"),
|
||||
Author: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts.Author", "models.Author"),
|
||||
},
|
||||
PostType: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts.PostType", "models.PostType"),
|
||||
},
|
||||
Comments: struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts.Comments", "models.Comment"),
|
||||
Author: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts.Comments.Author", "models.Author"),
|
||||
},
|
||||
Posts: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts.Comments.Posts", "models.Post"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Comments: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Comments", "models.Comment"),
|
||||
},
|
||||
}
|
||||
|
||||
_comment.Posts = commentManyToManyPosts{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Posts", "models.Post"),
|
||||
}
|
||||
|
||||
_comment.fillFieldMap()
|
||||
|
||||
return _comment
|
||||
}
|
||||
|
||||
type comment struct {
|
||||
commentDo
|
||||
|
||||
ALL field.Asterisk
|
||||
Id field.Uint
|
||||
Text field.String
|
||||
AuthorId field.Uint
|
||||
Author commentBelongsToAuthor
|
||||
|
||||
Posts commentManyToManyPosts
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (c comment) Table(newTableName string) *comment {
|
||||
c.commentDo.UseTable(newTableName)
|
||||
return c.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (c comment) As(alias string) *comment {
|
||||
c.commentDo.DO = *(c.commentDo.As(alias).(*gen.DO))
|
||||
return c.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (c *comment) updateTableName(table string) *comment {
|
||||
c.ALL = field.NewAsterisk(table)
|
||||
c.Id = field.NewUint(table, "id")
|
||||
c.Text = field.NewString(table, "text")
|
||||
c.AuthorId = field.NewUint(table, "author_id")
|
||||
|
||||
c.fillFieldMap()
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *comment) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := c.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (c *comment) fillFieldMap() {
|
||||
c.fieldMap = make(map[string]field.Expr, 5)
|
||||
c.fieldMap["id"] = c.Id
|
||||
c.fieldMap["text"] = c.Text
|
||||
c.fieldMap["author_id"] = c.AuthorId
|
||||
|
||||
}
|
||||
|
||||
func (c comment) clone(db *gorm.DB) comment {
|
||||
c.commentDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c comment) replaceDB(db *gorm.DB) comment {
|
||||
c.commentDo.ReplaceDB(db)
|
||||
return c
|
||||
}
|
||||
|
||||
type commentBelongsToAuthor struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
PostType struct {
|
||||
field.RelationField
|
||||
}
|
||||
Comments struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
}
|
||||
Comments struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
|
||||
func (a commentBelongsToAuthor) Where(conds ...field.Expr) *commentBelongsToAuthor {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a commentBelongsToAuthor) WithContext(ctx context.Context) *commentBelongsToAuthor {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a commentBelongsToAuthor) Session(session *gorm.Session) *commentBelongsToAuthor {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a commentBelongsToAuthor) Model(m *models.Comment) *commentBelongsToAuthorTx {
|
||||
return &commentBelongsToAuthorTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
type commentBelongsToAuthorTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a commentBelongsToAuthorTx) Find() (result *models.Author, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a commentBelongsToAuthorTx) Append(values ...*models.Author) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a commentBelongsToAuthorTx) Replace(values ...*models.Author) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a commentBelongsToAuthorTx) Delete(values ...*models.Author) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a commentBelongsToAuthorTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a commentBelongsToAuthorTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
type commentManyToManyPosts struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
}
|
||||
|
||||
func (a commentManyToManyPosts) Where(conds ...field.Expr) *commentManyToManyPosts {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a commentManyToManyPosts) WithContext(ctx context.Context) *commentManyToManyPosts {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a commentManyToManyPosts) Session(session *gorm.Session) *commentManyToManyPosts {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a commentManyToManyPosts) Model(m *models.Comment) *commentManyToManyPostsTx {
|
||||
return &commentManyToManyPostsTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
type commentManyToManyPostsTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a commentManyToManyPostsTx) Find() (result []*models.Post, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a commentManyToManyPostsTx) Append(values ...*models.Post) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a commentManyToManyPostsTx) Replace(values ...*models.Post) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a commentManyToManyPostsTx) Delete(values ...*models.Post) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a commentManyToManyPostsTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a commentManyToManyPostsTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
type commentDo struct{ gen.DO }
|
||||
|
||||
type ICommentDo interface {
|
||||
gen.SubQuery
|
||||
Debug() ICommentDo
|
||||
WithContext(ctx context.Context) ICommentDo
|
||||
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||
ReplaceDB(db *gorm.DB)
|
||||
ReadDB() ICommentDo
|
||||
WriteDB() ICommentDo
|
||||
As(alias string) gen.Dao
|
||||
Session(config *gorm.Session) ICommentDo
|
||||
Columns(cols ...field.Expr) gen.Columns
|
||||
Clauses(conds ...clause.Expression) ICommentDo
|
||||
Not(conds ...gen.Condition) ICommentDo
|
||||
Or(conds ...gen.Condition) ICommentDo
|
||||
Select(conds ...field.Expr) ICommentDo
|
||||
Where(conds ...gen.Condition) ICommentDo
|
||||
Order(conds ...field.Expr) ICommentDo
|
||||
Distinct(cols ...field.Expr) ICommentDo
|
||||
Omit(cols ...field.Expr) ICommentDo
|
||||
Join(table schema.Tabler, on ...field.Expr) ICommentDo
|
||||
LeftJoin(table schema.Tabler, on ...field.Expr) ICommentDo
|
||||
RightJoin(table schema.Tabler, on ...field.Expr) ICommentDo
|
||||
Group(cols ...field.Expr) ICommentDo
|
||||
Having(conds ...gen.Condition) ICommentDo
|
||||
Limit(limit int) ICommentDo
|
||||
Offset(offset int) ICommentDo
|
||||
Count() (count int64, err error)
|
||||
Scopes(funcs ...func(gen.Dao) gen.Dao) ICommentDo
|
||||
Unscoped() ICommentDo
|
||||
Create(values ...*models.Comment) error
|
||||
CreateInBatches(values []*models.Comment, batchSize int) error
|
||||
Save(values ...*models.Comment) error
|
||||
First() (*models.Comment, error)
|
||||
Take() (*models.Comment, error)
|
||||
Last() (*models.Comment, error)
|
||||
Find() ([]*models.Comment, error)
|
||||
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Comment, err error)
|
||||
FindInBatches(result *[]*models.Comment, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||
Pluck(column field.Expr, dest interface{}) error
|
||||
Delete(...*models.Comment) (info gen.ResultInfo, err error)
|
||||
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||
Attrs(attrs ...field.AssignExpr) ICommentDo
|
||||
Assign(attrs ...field.AssignExpr) ICommentDo
|
||||
Joins(fields ...field.RelationField) ICommentDo
|
||||
Preload(fields ...field.RelationField) ICommentDo
|
||||
FirstOrInit() (*models.Comment, error)
|
||||
FirstOrCreate() (*models.Comment, error)
|
||||
FindByPage(offset int, limit int) (result []*models.Comment, count int64, err error)
|
||||
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||
Scan(result interface{}) (err error)
|
||||
Returning(value interface{}, columns ...string) ICommentDo
|
||||
UnderlyingDB() *gorm.DB
|
||||
schema.Tabler
|
||||
}
|
||||
|
||||
func (c commentDo) Debug() ICommentDo {
|
||||
return c.withDO(c.DO.Debug())
|
||||
}
|
||||
|
||||
func (c commentDo) WithContext(ctx context.Context) ICommentDo {
|
||||
return c.withDO(c.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (c commentDo) ReadDB() ICommentDo {
|
||||
return c.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (c commentDo) WriteDB() ICommentDo {
|
||||
return c.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (c commentDo) Session(config *gorm.Session) ICommentDo {
|
||||
return c.withDO(c.DO.Session(config))
|
||||
}
|
||||
|
||||
func (c commentDo) Clauses(conds ...clause.Expression) ICommentDo {
|
||||
return c.withDO(c.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (c commentDo) Returning(value interface{}, columns ...string) ICommentDo {
|
||||
return c.withDO(c.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (c commentDo) Not(conds ...gen.Condition) ICommentDo {
|
||||
return c.withDO(c.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (c commentDo) Or(conds ...gen.Condition) ICommentDo {
|
||||
return c.withDO(c.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (c commentDo) Select(conds ...field.Expr) ICommentDo {
|
||||
return c.withDO(c.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (c commentDo) Where(conds ...gen.Condition) ICommentDo {
|
||||
return c.withDO(c.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (c commentDo) Order(conds ...field.Expr) ICommentDo {
|
||||
return c.withDO(c.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (c commentDo) Distinct(cols ...field.Expr) ICommentDo {
|
||||
return c.withDO(c.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (c commentDo) Omit(cols ...field.Expr) ICommentDo {
|
||||
return c.withDO(c.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (c commentDo) Join(table schema.Tabler, on ...field.Expr) ICommentDo {
|
||||
return c.withDO(c.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (c commentDo) LeftJoin(table schema.Tabler, on ...field.Expr) ICommentDo {
|
||||
return c.withDO(c.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c commentDo) RightJoin(table schema.Tabler, on ...field.Expr) ICommentDo {
|
||||
return c.withDO(c.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (c commentDo) Group(cols ...field.Expr) ICommentDo {
|
||||
return c.withDO(c.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (c commentDo) Having(conds ...gen.Condition) ICommentDo {
|
||||
return c.withDO(c.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (c commentDo) Limit(limit int) ICommentDo {
|
||||
return c.withDO(c.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (c commentDo) Offset(offset int) ICommentDo {
|
||||
return c.withDO(c.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (c commentDo) Scopes(funcs ...func(gen.Dao) gen.Dao) ICommentDo {
|
||||
return c.withDO(c.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (c commentDo) Unscoped() ICommentDo {
|
||||
return c.withDO(c.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (c commentDo) Create(values ...*models.Comment) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Create(values)
|
||||
}
|
||||
|
||||
func (c commentDo) CreateInBatches(values []*models.Comment, batchSize int) error {
|
||||
return c.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (c commentDo) Save(values ...*models.Comment) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return c.DO.Save(values)
|
||||
}
|
||||
|
||||
func (c commentDo) First() (*models.Comment, error) {
|
||||
if result, err := c.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.Comment), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c commentDo) Take() (*models.Comment, error) {
|
||||
if result, err := c.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.Comment), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c commentDo) Last() (*models.Comment, error) {
|
||||
if result, err := c.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.Comment), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c commentDo) Find() ([]*models.Comment, error) {
|
||||
result, err := c.DO.Find()
|
||||
return result.([]*models.Comment), err
|
||||
}
|
||||
|
||||
func (c commentDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Comment, err error) {
|
||||
buf := make([]*models.Comment, 0, batchSize)
|
||||
err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (c commentDo) FindInBatches(result *[]*models.Comment, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return c.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (c commentDo) Attrs(attrs ...field.AssignExpr) ICommentDo {
|
||||
return c.withDO(c.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (c commentDo) Assign(attrs ...field.AssignExpr) ICommentDo {
|
||||
return c.withDO(c.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (c commentDo) Joins(fields ...field.RelationField) ICommentDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Joins(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c commentDo) Preload(fields ...field.RelationField) ICommentDo {
|
||||
for _, _f := range fields {
|
||||
c = *c.withDO(c.DO.Preload(_f))
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c commentDo) FirstOrInit() (*models.Comment, error) {
|
||||
if result, err := c.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.Comment), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c commentDo) FirstOrCreate() (*models.Comment, error) {
|
||||
if result, err := c.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.Comment), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c commentDo) FindByPage(offset int, limit int) (result []*models.Comment, count int64, err error) {
|
||||
result, err = c.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = c.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (c commentDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = c.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = c.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c commentDo) Scan(result interface{}) (err error) {
|
||||
return c.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (c commentDo) Delete(models ...*models.Comment) (result gen.ResultInfo, err error) {
|
||||
return c.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (c *commentDo) withDO(do gen.Dao) *commentDo {
|
||||
c.DO = *do.(*gen.DO)
|
||||
return c
|
||||
}
|
||||
145
internal/dal/comments.gen_test.go
Normal file
145
internal/dal/comments.gen_test.go
Normal file
@@ -0,0 +1,145 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package dal
|
||||
|
||||
import (
|
||||
"app/internal/models"
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
func init() {
|
||||
InitializeDB()
|
||||
err := _gen_test_db.AutoMigrate(&models.Comment{})
|
||||
if err != nil {
|
||||
fmt.Printf("Error: AutoMigrate(&models.Comment{}) fail: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_commentQuery(t *testing.T) {
|
||||
comment := newComment(_gen_test_db)
|
||||
comment = *comment.As(comment.TableName())
|
||||
_do := comment.WithContext(context.Background()).Debug()
|
||||
|
||||
primaryKey := field.NewString(comment.TableName(), clause.PrimaryKey)
|
||||
_, err := _do.Unscoped().Where(primaryKey.IsNotNull()).Delete()
|
||||
if err != nil {
|
||||
t.Error("clean table <comments> fail:", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, ok := comment.GetFieldByName("")
|
||||
if ok {
|
||||
t.Error("GetFieldByName(\"\") from comment success")
|
||||
}
|
||||
|
||||
err = _do.Create(&models.Comment{})
|
||||
if err != nil {
|
||||
t.Error("create item in table <comments> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.Save(&models.Comment{})
|
||||
if err != nil {
|
||||
t.Error("create item in table <comments> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.CreateInBatches([]*models.Comment{{}, {}}, 10)
|
||||
if err != nil {
|
||||
t.Error("create item in table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Select(comment.ALL).Take()
|
||||
if err != nil {
|
||||
t.Error("Take() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.First()
|
||||
if err != nil {
|
||||
t.Error("First() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Last()
|
||||
if err != nil {
|
||||
t.Error("First() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil })
|
||||
if err != nil {
|
||||
t.Error("FindInBatch() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*models.Comment{}, 10, func(tx gen.Dao, batch int) error { return nil })
|
||||
if err != nil {
|
||||
t.Error("FindInBatches() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Select(comment.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find()
|
||||
if err != nil {
|
||||
t.Error("Find() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Distinct(primaryKey).Take()
|
||||
if err != nil {
|
||||
t.Error("select Distinct() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Select(comment.ALL).Omit(primaryKey).Take()
|
||||
if err != nil {
|
||||
t.Error("Omit() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Group(primaryKey).Find()
|
||||
if err != nil {
|
||||
t.Error("Group() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find()
|
||||
if err != nil {
|
||||
t.Error("Scopes() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, _, err = _do.FindByPage(0, 1)
|
||||
if err != nil {
|
||||
t.Error("FindByPage() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.ScanByPage(&models.Comment{}, 0, 1)
|
||||
if err != nil {
|
||||
t.Error("ScanByPage() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit()
|
||||
if err != nil {
|
||||
t.Error("FirstOrInit() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate()
|
||||
if err != nil {
|
||||
t.Error("FirstOrCreate() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
var _a _another
|
||||
var _aPK = field.NewString(_a.TableName(), "id")
|
||||
|
||||
err = _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{})
|
||||
if err != nil {
|
||||
t.Error("Join() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{})
|
||||
if err != nil {
|
||||
t.Error("LeftJoin() on table <comments> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Not().Or().Clauses().Take()
|
||||
if err != nil {
|
||||
t.Error("Not/Or/Clauses on table <comments> fail:", err)
|
||||
}
|
||||
}
|
||||
@@ -17,25 +17,37 @@ import (
|
||||
|
||||
var (
|
||||
Q = new(Query)
|
||||
Author *author
|
||||
Comment *comment
|
||||
Post *post
|
||||
PostType *postType
|
||||
)
|
||||
|
||||
func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
|
||||
*Q = *Use(db, opts...)
|
||||
Author = &Q.Author
|
||||
Comment = &Q.Comment
|
||||
Post = &Q.Post
|
||||
PostType = &Q.PostType
|
||||
}
|
||||
|
||||
func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
Author: newAuthor(db, opts...),
|
||||
Comment: newComment(db, opts...),
|
||||
Post: newPost(db, opts...),
|
||||
PostType: newPostType(db, opts...),
|
||||
}
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
db *gorm.DB
|
||||
|
||||
Author author
|
||||
Comment comment
|
||||
Post post
|
||||
PostType postType
|
||||
}
|
||||
|
||||
func (q *Query) Available() bool { return q.db != nil }
|
||||
@@ -43,7 +55,10 @@ func (q *Query) Available() bool { return q.db != nil }
|
||||
func (q *Query) clone(db *gorm.DB) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
Author: q.Author.clone(db),
|
||||
Comment: q.Comment.clone(db),
|
||||
Post: q.Post.clone(db),
|
||||
PostType: q.PostType.clone(db),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,17 +73,26 @@ func (q *Query) WriteDB() *Query {
|
||||
func (q *Query) ReplaceDB(db *gorm.DB) *Query {
|
||||
return &Query{
|
||||
db: db,
|
||||
Author: q.Author.replaceDB(db),
|
||||
Comment: q.Comment.replaceDB(db),
|
||||
Post: q.Post.replaceDB(db),
|
||||
PostType: q.PostType.replaceDB(db),
|
||||
}
|
||||
}
|
||||
|
||||
type queryCtx struct {
|
||||
Author IAuthorDo
|
||||
Comment ICommentDo
|
||||
Post IPostDo
|
||||
PostType IPostTypeDo
|
||||
}
|
||||
|
||||
func (q *Query) WithContext(ctx context.Context) *queryCtx {
|
||||
return &queryCtx{
|
||||
Author: q.Author.WithContext(ctx),
|
||||
Comment: q.Comment.WithContext(ctx),
|
||||
Post: q.Post.WithContext(ctx),
|
||||
PostType: q.PostType.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
internal/dal/gen_test.db
Normal file
BIN
internal/dal/gen_test.db
Normal file
Binary file not shown.
@@ -77,7 +77,10 @@ func Test_WithContext(t *testing.T) {
|
||||
qCtx := query.WithContext(context.WithValue(context.Background(), key, value))
|
||||
|
||||
for _, ctx := range []context.Context{
|
||||
qCtx.Author.UnderlyingDB().Statement.Context,
|
||||
qCtx.Comment.UnderlyingDB().Statement.Context,
|
||||
qCtx.Post.UnderlyingDB().Statement.Context,
|
||||
qCtx.PostType.UnderlyingDB().Statement.Context,
|
||||
} {
|
||||
if v := ctx.Value(key); v != value {
|
||||
t.Errorf("get value from context fail, expect %q, got %q", value, v)
|
||||
|
||||
383
internal/dal/post_types.gen.go
Normal file
383
internal/dal/post_types.gen.go
Normal file
@@ -0,0 +1,383 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package dal
|
||||
|
||||
import (
|
||||
"app/internal/models"
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
|
||||
"gorm.io/plugin/dbresolver"
|
||||
)
|
||||
|
||||
func newPostType(db *gorm.DB, opts ...gen.DOOption) postType {
|
||||
_postType := postType{}
|
||||
|
||||
_postType.postTypeDo.UseDB(db, opts...)
|
||||
_postType.postTypeDo.UseModel(&models.PostType{})
|
||||
|
||||
tableName := _postType.postTypeDo.TableName()
|
||||
_postType.ALL = field.NewAsterisk(tableName)
|
||||
_postType.Id = field.NewUint(tableName, "id")
|
||||
_postType.Name = field.NewString(tableName, "name")
|
||||
|
||||
_postType.fillFieldMap()
|
||||
|
||||
return _postType
|
||||
}
|
||||
|
||||
type postType struct {
|
||||
postTypeDo
|
||||
|
||||
ALL field.Asterisk
|
||||
Id field.Uint
|
||||
Name field.String
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
|
||||
func (p postType) Table(newTableName string) *postType {
|
||||
p.postTypeDo.UseTable(newTableName)
|
||||
return p.updateTableName(newTableName)
|
||||
}
|
||||
|
||||
func (p postType) As(alias string) *postType {
|
||||
p.postTypeDo.DO = *(p.postTypeDo.As(alias).(*gen.DO))
|
||||
return p.updateTableName(alias)
|
||||
}
|
||||
|
||||
func (p *postType) updateTableName(table string) *postType {
|
||||
p.ALL = field.NewAsterisk(table)
|
||||
p.Id = field.NewUint(table, "id")
|
||||
p.Name = field.NewString(table, "name")
|
||||
|
||||
p.fillFieldMap()
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *postType) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
_f, ok := p.fieldMap[fieldName]
|
||||
if !ok || _f == nil {
|
||||
return nil, false
|
||||
}
|
||||
_oe, ok := _f.(field.OrderExpr)
|
||||
return _oe, ok
|
||||
}
|
||||
|
||||
func (p *postType) fillFieldMap() {
|
||||
p.fieldMap = make(map[string]field.Expr, 2)
|
||||
p.fieldMap["id"] = p.Id
|
||||
p.fieldMap["name"] = p.Name
|
||||
}
|
||||
|
||||
func (p postType) clone(db *gorm.DB) postType {
|
||||
p.postTypeDo.ReplaceConnPool(db.Statement.ConnPool)
|
||||
return p
|
||||
}
|
||||
|
||||
func (p postType) replaceDB(db *gorm.DB) postType {
|
||||
p.postTypeDo.ReplaceDB(db)
|
||||
return p
|
||||
}
|
||||
|
||||
type postTypeDo struct{ gen.DO }
|
||||
|
||||
type IPostTypeDo interface {
|
||||
gen.SubQuery
|
||||
Debug() IPostTypeDo
|
||||
WithContext(ctx context.Context) IPostTypeDo
|
||||
WithResult(fc func(tx gen.Dao)) gen.ResultInfo
|
||||
ReplaceDB(db *gorm.DB)
|
||||
ReadDB() IPostTypeDo
|
||||
WriteDB() IPostTypeDo
|
||||
As(alias string) gen.Dao
|
||||
Session(config *gorm.Session) IPostTypeDo
|
||||
Columns(cols ...field.Expr) gen.Columns
|
||||
Clauses(conds ...clause.Expression) IPostTypeDo
|
||||
Not(conds ...gen.Condition) IPostTypeDo
|
||||
Or(conds ...gen.Condition) IPostTypeDo
|
||||
Select(conds ...field.Expr) IPostTypeDo
|
||||
Where(conds ...gen.Condition) IPostTypeDo
|
||||
Order(conds ...field.Expr) IPostTypeDo
|
||||
Distinct(cols ...field.Expr) IPostTypeDo
|
||||
Omit(cols ...field.Expr) IPostTypeDo
|
||||
Join(table schema.Tabler, on ...field.Expr) IPostTypeDo
|
||||
LeftJoin(table schema.Tabler, on ...field.Expr) IPostTypeDo
|
||||
RightJoin(table schema.Tabler, on ...field.Expr) IPostTypeDo
|
||||
Group(cols ...field.Expr) IPostTypeDo
|
||||
Having(conds ...gen.Condition) IPostTypeDo
|
||||
Limit(limit int) IPostTypeDo
|
||||
Offset(offset int) IPostTypeDo
|
||||
Count() (count int64, err error)
|
||||
Scopes(funcs ...func(gen.Dao) gen.Dao) IPostTypeDo
|
||||
Unscoped() IPostTypeDo
|
||||
Create(values ...*models.PostType) error
|
||||
CreateInBatches(values []*models.PostType, batchSize int) error
|
||||
Save(values ...*models.PostType) error
|
||||
First() (*models.PostType, error)
|
||||
Take() (*models.PostType, error)
|
||||
Last() (*models.PostType, error)
|
||||
Find() ([]*models.PostType, error)
|
||||
FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.PostType, err error)
|
||||
FindInBatches(result *[]*models.PostType, batchSize int, fc func(tx gen.Dao, batch int) error) error
|
||||
Pluck(column field.Expr, dest interface{}) error
|
||||
Delete(...*models.PostType) (info gen.ResultInfo, err error)
|
||||
Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
Updates(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
|
||||
UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
|
||||
UpdateFrom(q gen.SubQuery) gen.Dao
|
||||
Attrs(attrs ...field.AssignExpr) IPostTypeDo
|
||||
Assign(attrs ...field.AssignExpr) IPostTypeDo
|
||||
Joins(fields ...field.RelationField) IPostTypeDo
|
||||
Preload(fields ...field.RelationField) IPostTypeDo
|
||||
FirstOrInit() (*models.PostType, error)
|
||||
FirstOrCreate() (*models.PostType, error)
|
||||
FindByPage(offset int, limit int) (result []*models.PostType, count int64, err error)
|
||||
ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
|
||||
Scan(result interface{}) (err error)
|
||||
Returning(value interface{}, columns ...string) IPostTypeDo
|
||||
UnderlyingDB() *gorm.DB
|
||||
schema.Tabler
|
||||
}
|
||||
|
||||
func (p postTypeDo) Debug() IPostTypeDo {
|
||||
return p.withDO(p.DO.Debug())
|
||||
}
|
||||
|
||||
func (p postTypeDo) WithContext(ctx context.Context) IPostTypeDo {
|
||||
return p.withDO(p.DO.WithContext(ctx))
|
||||
}
|
||||
|
||||
func (p postTypeDo) ReadDB() IPostTypeDo {
|
||||
return p.Clauses(dbresolver.Read)
|
||||
}
|
||||
|
||||
func (p postTypeDo) WriteDB() IPostTypeDo {
|
||||
return p.Clauses(dbresolver.Write)
|
||||
}
|
||||
|
||||
func (p postTypeDo) Session(config *gorm.Session) IPostTypeDo {
|
||||
return p.withDO(p.DO.Session(config))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Clauses(conds ...clause.Expression) IPostTypeDo {
|
||||
return p.withDO(p.DO.Clauses(conds...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Returning(value interface{}, columns ...string) IPostTypeDo {
|
||||
return p.withDO(p.DO.Returning(value, columns...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Not(conds ...gen.Condition) IPostTypeDo {
|
||||
return p.withDO(p.DO.Not(conds...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Or(conds ...gen.Condition) IPostTypeDo {
|
||||
return p.withDO(p.DO.Or(conds...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Select(conds ...field.Expr) IPostTypeDo {
|
||||
return p.withDO(p.DO.Select(conds...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Where(conds ...gen.Condition) IPostTypeDo {
|
||||
return p.withDO(p.DO.Where(conds...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Order(conds ...field.Expr) IPostTypeDo {
|
||||
return p.withDO(p.DO.Order(conds...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Distinct(cols ...field.Expr) IPostTypeDo {
|
||||
return p.withDO(p.DO.Distinct(cols...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Omit(cols ...field.Expr) IPostTypeDo {
|
||||
return p.withDO(p.DO.Omit(cols...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Join(table schema.Tabler, on ...field.Expr) IPostTypeDo {
|
||||
return p.withDO(p.DO.Join(table, on...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) LeftJoin(table schema.Tabler, on ...field.Expr) IPostTypeDo {
|
||||
return p.withDO(p.DO.LeftJoin(table, on...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) RightJoin(table schema.Tabler, on ...field.Expr) IPostTypeDo {
|
||||
return p.withDO(p.DO.RightJoin(table, on...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Group(cols ...field.Expr) IPostTypeDo {
|
||||
return p.withDO(p.DO.Group(cols...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Having(conds ...gen.Condition) IPostTypeDo {
|
||||
return p.withDO(p.DO.Having(conds...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Limit(limit int) IPostTypeDo {
|
||||
return p.withDO(p.DO.Limit(limit))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Offset(offset int) IPostTypeDo {
|
||||
return p.withDO(p.DO.Offset(offset))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IPostTypeDo {
|
||||
return p.withDO(p.DO.Scopes(funcs...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Unscoped() IPostTypeDo {
|
||||
return p.withDO(p.DO.Unscoped())
|
||||
}
|
||||
|
||||
func (p postTypeDo) Create(values ...*models.PostType) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return p.DO.Create(values)
|
||||
}
|
||||
|
||||
func (p postTypeDo) CreateInBatches(values []*models.PostType, batchSize int) error {
|
||||
return p.DO.CreateInBatches(values, batchSize)
|
||||
}
|
||||
|
||||
// Save : !!! underlying implementation is different with GORM
|
||||
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
|
||||
func (p postTypeDo) Save(values ...*models.PostType) error {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return p.DO.Save(values)
|
||||
}
|
||||
|
||||
func (p postTypeDo) First() (*models.PostType, error) {
|
||||
if result, err := p.DO.First(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.PostType), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p postTypeDo) Take() (*models.PostType, error) {
|
||||
if result, err := p.DO.Take(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.PostType), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p postTypeDo) Last() (*models.PostType, error) {
|
||||
if result, err := p.DO.Last(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.PostType), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p postTypeDo) Find() ([]*models.PostType, error) {
|
||||
result, err := p.DO.Find()
|
||||
return result.([]*models.PostType), err
|
||||
}
|
||||
|
||||
func (p postTypeDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.PostType, err error) {
|
||||
buf := make([]*models.PostType, 0, batchSize)
|
||||
err = p.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
|
||||
defer func() { results = append(results, buf...) }()
|
||||
return fc(tx, batch)
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (p postTypeDo) FindInBatches(result *[]*models.PostType, batchSize int, fc func(tx gen.Dao, batch int) error) error {
|
||||
return p.DO.FindInBatches(result, batchSize, fc)
|
||||
}
|
||||
|
||||
func (p postTypeDo) Attrs(attrs ...field.AssignExpr) IPostTypeDo {
|
||||
return p.withDO(p.DO.Attrs(attrs...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Assign(attrs ...field.AssignExpr) IPostTypeDo {
|
||||
return p.withDO(p.DO.Assign(attrs...))
|
||||
}
|
||||
|
||||
func (p postTypeDo) Joins(fields ...field.RelationField) IPostTypeDo {
|
||||
for _, _f := range fields {
|
||||
p = *p.withDO(p.DO.Joins(_f))
|
||||
}
|
||||
return &p
|
||||
}
|
||||
|
||||
func (p postTypeDo) Preload(fields ...field.RelationField) IPostTypeDo {
|
||||
for _, _f := range fields {
|
||||
p = *p.withDO(p.DO.Preload(_f))
|
||||
}
|
||||
return &p
|
||||
}
|
||||
|
||||
func (p postTypeDo) FirstOrInit() (*models.PostType, error) {
|
||||
if result, err := p.DO.FirstOrInit(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.PostType), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p postTypeDo) FirstOrCreate() (*models.PostType, error) {
|
||||
if result, err := p.DO.FirstOrCreate(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return result.(*models.PostType), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p postTypeDo) FindByPage(offset int, limit int) (result []*models.PostType, count int64, err error) {
|
||||
result, err = p.Offset(offset).Limit(limit).Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if size := len(result); 0 < limit && 0 < size && size < limit {
|
||||
count = int64(size + offset)
|
||||
return
|
||||
}
|
||||
|
||||
count, err = p.Offset(-1).Limit(-1).Count()
|
||||
return
|
||||
}
|
||||
|
||||
func (p postTypeDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
|
||||
count, err = p.Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = p.Offset(offset).Limit(limit).Scan(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (p postTypeDo) Scan(result interface{}) (err error) {
|
||||
return p.DO.Scan(result)
|
||||
}
|
||||
|
||||
func (p postTypeDo) Delete(models ...*models.PostType) (result gen.ResultInfo, err error) {
|
||||
return p.DO.Delete(models)
|
||||
}
|
||||
|
||||
func (p *postTypeDo) withDO(do gen.Dao) *postTypeDo {
|
||||
p.DO = *do.(*gen.DO)
|
||||
return p
|
||||
}
|
||||
145
internal/dal/post_types.gen_test.go
Normal file
145
internal/dal/post_types.gen_test.go
Normal file
@@ -0,0 +1,145 @@
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
// Code generated by gorm.io/gen. DO NOT EDIT.
|
||||
|
||||
package dal
|
||||
|
||||
import (
|
||||
"app/internal/models"
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
func init() {
|
||||
InitializeDB()
|
||||
err := _gen_test_db.AutoMigrate(&models.PostType{})
|
||||
if err != nil {
|
||||
fmt.Printf("Error: AutoMigrate(&models.PostType{}) fail: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_postTypeQuery(t *testing.T) {
|
||||
postType := newPostType(_gen_test_db)
|
||||
postType = *postType.As(postType.TableName())
|
||||
_do := postType.WithContext(context.Background()).Debug()
|
||||
|
||||
primaryKey := field.NewString(postType.TableName(), clause.PrimaryKey)
|
||||
_, err := _do.Unscoped().Where(primaryKey.IsNotNull()).Delete()
|
||||
if err != nil {
|
||||
t.Error("clean table <post_types> fail:", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, ok := postType.GetFieldByName("")
|
||||
if ok {
|
||||
t.Error("GetFieldByName(\"\") from postType success")
|
||||
}
|
||||
|
||||
err = _do.Create(&models.PostType{})
|
||||
if err != nil {
|
||||
t.Error("create item in table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.Save(&models.PostType{})
|
||||
if err != nil {
|
||||
t.Error("create item in table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.CreateInBatches([]*models.PostType{{}, {}}, 10)
|
||||
if err != nil {
|
||||
t.Error("create item in table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Select(postType.ALL).Take()
|
||||
if err != nil {
|
||||
t.Error("Take() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.First()
|
||||
if err != nil {
|
||||
t.Error("First() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Last()
|
||||
if err != nil {
|
||||
t.Error("First() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Where(primaryKey.IsNotNull()).FindInBatch(10, func(tx gen.Dao, batch int) error { return nil })
|
||||
if err != nil {
|
||||
t.Error("FindInBatch() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.Where(primaryKey.IsNotNull()).FindInBatches(&[]*models.PostType{}, 10, func(tx gen.Dao, batch int) error { return nil })
|
||||
if err != nil {
|
||||
t.Error("FindInBatches() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Select(postType.ALL).Where(primaryKey.IsNotNull()).Order(primaryKey.Desc()).Find()
|
||||
if err != nil {
|
||||
t.Error("Find() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Distinct(primaryKey).Take()
|
||||
if err != nil {
|
||||
t.Error("select Distinct() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Select(postType.ALL).Omit(primaryKey).Take()
|
||||
if err != nil {
|
||||
t.Error("Omit() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Group(primaryKey).Find()
|
||||
if err != nil {
|
||||
t.Error("Group() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Scopes(func(dao gen.Dao) gen.Dao { return dao.Where(primaryKey.IsNotNull()) }).Find()
|
||||
if err != nil {
|
||||
t.Error("Scopes() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, _, err = _do.FindByPage(0, 1)
|
||||
if err != nil {
|
||||
t.Error("FindByPage() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.ScanByPage(&models.PostType{}, 0, 1)
|
||||
if err != nil {
|
||||
t.Error("ScanByPage() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrInit()
|
||||
if err != nil {
|
||||
t.Error("FirstOrInit() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Attrs(primaryKey).Assign(primaryKey).FirstOrCreate()
|
||||
if err != nil {
|
||||
t.Error("FirstOrCreate() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
var _a _another
|
||||
var _aPK = field.NewString(_a.TableName(), "id")
|
||||
|
||||
err = _do.Join(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{})
|
||||
if err != nil {
|
||||
t.Error("Join() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
err = _do.LeftJoin(&_a, primaryKey.EqCol(_aPK)).Scan(map[string]interface{}{})
|
||||
if err != nil {
|
||||
t.Error("LeftJoin() on table <post_types> fail:", err)
|
||||
}
|
||||
|
||||
_, err = _do.Not().Or().Clauses().Take()
|
||||
if err != nil {
|
||||
t.Error("Not/Or/Clauses on table <post_types> fail:", err)
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,9 @@
|
||||
package dal
|
||||
|
||||
import (
|
||||
"app/internal/models"
|
||||
"context"
|
||||
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/models"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
@@ -28,7 +28,83 @@ func newPost(db *gorm.DB, opts ...gen.DOOption) post {
|
||||
_post.ALL = field.NewAsterisk(tableName)
|
||||
_post.Id = field.NewUint(tableName, "id")
|
||||
_post.Text = field.NewString(tableName, "text")
|
||||
_post.CreatedAt = field.NewUint(tableName, "created_at")
|
||||
_post.Deadline = field.NewInt64(tableName, "deadline")
|
||||
_post.CreatedAt = field.NewInt64(tableName, "created_at")
|
||||
_post.AuthorId = field.NewUint(tableName, "author_id")
|
||||
_post.PostTypeId = field.NewUint(tableName, "post_type_id")
|
||||
_post.Author = postBelongsToAuthor{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Author", "models.Author"),
|
||||
Posts: struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
PostType struct {
|
||||
field.RelationField
|
||||
}
|
||||
Comments struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts", "models.Post"),
|
||||
Author: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts.Author", "models.Author"),
|
||||
},
|
||||
PostType: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts.PostType", "models.PostType"),
|
||||
},
|
||||
Comments: struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
}
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts.Comments", "models.Comment"),
|
||||
Author: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts.Comments.Author", "models.Author"),
|
||||
},
|
||||
Posts: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Posts.Comments.Posts", "models.Post"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Comments: struct {
|
||||
field.RelationField
|
||||
}{
|
||||
RelationField: field.NewRelation("Author.Comments", "models.Comment"),
|
||||
},
|
||||
}
|
||||
|
||||
_post.PostType = postBelongsToPostType{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("PostType", "models.PostType"),
|
||||
}
|
||||
|
||||
_post.Comments = postManyToManyComments{
|
||||
db: db.Session(&gorm.Session{}),
|
||||
|
||||
RelationField: field.NewRelation("Comments", "models.Comment"),
|
||||
}
|
||||
|
||||
_post.fillFieldMap()
|
||||
|
||||
@@ -41,7 +117,15 @@ type post struct {
|
||||
ALL field.Asterisk
|
||||
Id field.Uint
|
||||
Text field.String
|
||||
CreatedAt field.Uint
|
||||
Deadline field.Int64
|
||||
CreatedAt field.Int64
|
||||
AuthorId field.Uint
|
||||
PostTypeId field.Uint
|
||||
Author postBelongsToAuthor
|
||||
|
||||
PostType postBelongsToPostType
|
||||
|
||||
Comments postManyToManyComments
|
||||
|
||||
fieldMap map[string]field.Expr
|
||||
}
|
||||
@@ -60,7 +144,10 @@ func (p *post) updateTableName(table string) *post {
|
||||
p.ALL = field.NewAsterisk(table)
|
||||
p.Id = field.NewUint(table, "id")
|
||||
p.Text = field.NewString(table, "text")
|
||||
p.CreatedAt = field.NewUint(table, "created_at")
|
||||
p.Deadline = field.NewInt64(table, "deadline")
|
||||
p.CreatedAt = field.NewInt64(table, "created_at")
|
||||
p.AuthorId = field.NewUint(table, "author_id")
|
||||
p.PostTypeId = field.NewUint(table, "post_type_id")
|
||||
|
||||
p.fillFieldMap()
|
||||
|
||||
@@ -77,10 +164,14 @@ func (p *post) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
|
||||
}
|
||||
|
||||
func (p *post) fillFieldMap() {
|
||||
p.fieldMap = make(map[string]field.Expr, 3)
|
||||
p.fieldMap = make(map[string]field.Expr, 9)
|
||||
p.fieldMap["id"] = p.Id
|
||||
p.fieldMap["text"] = p.Text
|
||||
p.fieldMap["deadline"] = p.Deadline
|
||||
p.fieldMap["created_at"] = p.CreatedAt
|
||||
p.fieldMap["author_id"] = p.AuthorId
|
||||
p.fieldMap["post_type_id"] = p.PostTypeId
|
||||
|
||||
}
|
||||
|
||||
func (p post) clone(db *gorm.DB) post {
|
||||
@@ -93,6 +184,241 @@ func (p post) replaceDB(db *gorm.DB) post {
|
||||
return p
|
||||
}
|
||||
|
||||
type postBelongsToAuthor struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
PostType struct {
|
||||
field.RelationField
|
||||
}
|
||||
Comments struct {
|
||||
field.RelationField
|
||||
Author struct {
|
||||
field.RelationField
|
||||
}
|
||||
Posts struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
}
|
||||
Comments struct {
|
||||
field.RelationField
|
||||
}
|
||||
}
|
||||
|
||||
func (a postBelongsToAuthor) Where(conds ...field.Expr) *postBelongsToAuthor {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a postBelongsToAuthor) WithContext(ctx context.Context) *postBelongsToAuthor {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a postBelongsToAuthor) Session(session *gorm.Session) *postBelongsToAuthor {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a postBelongsToAuthor) Model(m *models.Post) *postBelongsToAuthorTx {
|
||||
return &postBelongsToAuthorTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
type postBelongsToAuthorTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a postBelongsToAuthorTx) Find() (result *models.Author, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a postBelongsToAuthorTx) Append(values ...*models.Author) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a postBelongsToAuthorTx) Replace(values ...*models.Author) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a postBelongsToAuthorTx) Delete(values ...*models.Author) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a postBelongsToAuthorTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a postBelongsToAuthorTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
type postBelongsToPostType struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
}
|
||||
|
||||
func (a postBelongsToPostType) Where(conds ...field.Expr) *postBelongsToPostType {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a postBelongsToPostType) WithContext(ctx context.Context) *postBelongsToPostType {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a postBelongsToPostType) Session(session *gorm.Session) *postBelongsToPostType {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a postBelongsToPostType) Model(m *models.Post) *postBelongsToPostTypeTx {
|
||||
return &postBelongsToPostTypeTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
type postBelongsToPostTypeTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a postBelongsToPostTypeTx) Find() (result *models.PostType, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a postBelongsToPostTypeTx) Append(values ...*models.PostType) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a postBelongsToPostTypeTx) Replace(values ...*models.PostType) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a postBelongsToPostTypeTx) Delete(values ...*models.PostType) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a postBelongsToPostTypeTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a postBelongsToPostTypeTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
type postManyToManyComments struct {
|
||||
db *gorm.DB
|
||||
|
||||
field.RelationField
|
||||
}
|
||||
|
||||
func (a postManyToManyComments) Where(conds ...field.Expr) *postManyToManyComments {
|
||||
if len(conds) == 0 {
|
||||
return &a
|
||||
}
|
||||
|
||||
exprs := make([]clause.Expression, 0, len(conds))
|
||||
for _, cond := range conds {
|
||||
exprs = append(exprs, cond.BeCond().(clause.Expression))
|
||||
}
|
||||
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a postManyToManyComments) WithContext(ctx context.Context) *postManyToManyComments {
|
||||
a.db = a.db.WithContext(ctx)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a postManyToManyComments) Session(session *gorm.Session) *postManyToManyComments {
|
||||
a.db = a.db.Session(session)
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a postManyToManyComments) Model(m *models.Post) *postManyToManyCommentsTx {
|
||||
return &postManyToManyCommentsTx{a.db.Model(m).Association(a.Name())}
|
||||
}
|
||||
|
||||
type postManyToManyCommentsTx struct{ tx *gorm.Association }
|
||||
|
||||
func (a postManyToManyCommentsTx) Find() (result []*models.Comment, err error) {
|
||||
return result, a.tx.Find(&result)
|
||||
}
|
||||
|
||||
func (a postManyToManyCommentsTx) Append(values ...*models.Comment) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Append(targetValues...)
|
||||
}
|
||||
|
||||
func (a postManyToManyCommentsTx) Replace(values ...*models.Comment) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Replace(targetValues...)
|
||||
}
|
||||
|
||||
func (a postManyToManyCommentsTx) Delete(values ...*models.Comment) (err error) {
|
||||
targetValues := make([]interface{}, len(values))
|
||||
for i, v := range values {
|
||||
targetValues[i] = v
|
||||
}
|
||||
return a.tx.Delete(targetValues...)
|
||||
}
|
||||
|
||||
func (a postManyToManyCommentsTx) Clear() error {
|
||||
return a.tx.Clear()
|
||||
}
|
||||
|
||||
func (a postManyToManyCommentsTx) Count() int64 {
|
||||
return a.tx.Count()
|
||||
}
|
||||
|
||||
type postDo struct{ gen.DO }
|
||||
|
||||
type IPostDo interface {
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
package dal
|
||||
|
||||
import (
|
||||
"app/internal/models"
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/models"
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm/clause"
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/dal"
|
||||
"github.com/ncruces/go-sqlite3"
|
||||
"github.com/ncruces/go-sqlite3/driver"
|
||||
"app/internal/dal"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
_ "github.com/ncruces/go-sqlite3/embed"
|
||||
"github.com/ncruces/go-sqlite3/ext/unicode"
|
||||
"github.com/ncruces/go-sqlite3/gormlite"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
@@ -38,14 +31,13 @@ func initialize() error {
|
||||
Colorful: true, // Disable color
|
||||
},
|
||||
)
|
||||
db, err = gorm.Open(gormlite.Open("file:"+Path+"?_fk=1"), &gorm.Config{
|
||||
db, err = gorm.Open(sqlite.Open("file:"+Path+"?_fk=1"), &gorm.Config{
|
||||
Logger: newLogger,
|
||||
FullSaveAssociations: false,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
RegisterUnicodeExtension(db)
|
||||
if res := db.Exec(`PRAGMA foreign_keys = ON`); res.Error != nil {
|
||||
return res.Error
|
||||
}
|
||||
@@ -93,59 +85,3 @@ func GetInstance() *gorm.DB {
|
||||
})
|
||||
return db
|
||||
}
|
||||
|
||||
func RegisterUnicodeExtension(db *gorm.DB) {
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
conn, err := sqlDB.Conn(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer func(conn *sql.Conn) {
|
||||
err := conn.Close()
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
}
|
||||
}(conn)
|
||||
|
||||
err = conn.Raw(func(driverConn any) error {
|
||||
c := driverConn.(driver.Conn)
|
||||
sqliteConn := c.Raw()
|
||||
|
||||
if err := unicode.Register(sqliteConn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := sqliteConn.Exec(`SELECT icu_load_collation('ru-RU', 'russian')`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := sqliteConn.Exec(`SELECT icu_load_collation('en-US', 'english')`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stmt, _, err := sqliteConn.Prepare(`SELECT 'ы' LIKE 'Ы'`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(stmt *sqlite3.Stmt) {
|
||||
err := stmt.Close()
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
}
|
||||
}(stmt)
|
||||
|
||||
if stmt.Step() {
|
||||
slog.Info("ICU test result", "value", stmt.ColumnBool(0))
|
||||
}
|
||||
return stmt.Err()
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/models"
|
||||
"app/internal/models"
|
||||
|
||||
"gorm.io/gen"
|
||||
)
|
||||
|
||||
@@ -1,9 +1,37 @@
|
||||
package models
|
||||
|
||||
var Entities = []any{&Post{}}
|
||||
var Entities = []any{
|
||||
&Post{}, &Author{}, &PostType{}, &Comment{},
|
||||
}
|
||||
|
||||
type PostType struct {
|
||||
Id uint `gorm:"primaryKey" ui:"hidden"`
|
||||
Name string `ui:"label:Название;"`
|
||||
}
|
||||
|
||||
type Post struct {
|
||||
Id uint `gorm:"primaryKey" ui:"hidden;label:\"Номер поста\""`
|
||||
Text string `ui:"label:Текст"`
|
||||
Deadline int64 `ui:"label:Дедлайн;datatype:datetime;"`
|
||||
CreatedAt int64 `gorm:"autoCreateTime" ui:"label:Время создания;readonly;datatype:datetime;"`
|
||||
AuthorId uint `ui:"hidden" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
||||
Author Author `ui:"label:Автор; field:Name;"`
|
||||
PostTypeId uint `ui:"hidden; excel:Номер типа поста;"`
|
||||
PostType PostType `ui:"label:Тип поста; field:Name;" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
||||
Comments []Comment `ui:"label:Комментарии; field:Text;" gorm:"many2many:comments_post;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
||||
}
|
||||
|
||||
type Author struct {
|
||||
Id uint `gorm:"primaryKey" ui:"hidden"`
|
||||
Name string `ui:"label:Имя;"`
|
||||
Posts []Post `ui:"label:Посты; field:Text;" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
||||
Comments []Comment `ui:"label:Комментарии; field:Text;" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
||||
}
|
||||
|
||||
type Comment struct {
|
||||
Id uint `gorm:"primaryKey" ui:"hidden"`
|
||||
Text string `ui:"label:Текст;"`
|
||||
CreatedAt uint `gorm:"autoCreateTime" ui:"readonly"`
|
||||
AuthorId uint `ui:"hidden"`
|
||||
Author Author `ui:"label:Автор; field:Name;" gorm:"foreignKey:AuthorId;references:Id;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
||||
Posts []Post `ui:"label:Посты; field:Text;" gorm:"many2many:comments_post;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
|
||||
}
|
||||
|
||||
66
internal/services/author.go
Normal file
66
internal/services/author.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"app/internal/dal"
|
||||
"app/internal/database"
|
||||
"app/internal/models"
|
||||
"app/internal/utils"
|
||||
"errors"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type AuthorService struct {
|
||||
}
|
||||
type Author = models.Author
|
||||
|
||||
func (service *AuthorService) Create(item Author) (Author, error) {
|
||||
utils.ReplaceEmptySlicesWithNil(&item)
|
||||
err := dal.Author.Create(&item)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
err = utils.AppendAssociations(database.GetInstance(), &item)
|
||||
return item, err
|
||||
}
|
||||
func (service *AuthorService) GetAll() ([]*Author, error) {
|
||||
var authors []*Author
|
||||
authors, err := dal.Author.Preload(field.Associations).Find()
|
||||
return authors, err
|
||||
}
|
||||
func (service *AuthorService) GetById(id uint) (*Author, error) {
|
||||
item, err := dal.Author.Preload(field.Associations).Where(dal.Author.Id.Eq(id)).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
func (service *AuthorService) Update(item Author) (Author, error) {
|
||||
utils.ReplaceEmptySlicesWithNil(&item)
|
||||
_, err := dal.Author.Updates(&item)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
err = utils.UpdateAssociations(database.GetInstance(), &item)
|
||||
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
|
||||
return item, err
|
||||
}
|
||||
func (service *AuthorService) Delete(id uint) error {
|
||||
_, err := dal.Author.Unscoped().Where(dal.Author.Id.Eq(id)).Delete()
|
||||
return err
|
||||
}
|
||||
func (service *AuthorService) Count() (int64, error) {
|
||||
amount, err := dal.Author.Count()
|
||||
return amount, err
|
||||
}
|
||||
func (service *AuthorService) SortedByOrder(fieldsSortOrder map[string]string) ([]*Author, error) {
|
||||
return utils.SortByOrder(fieldsSortOrder, Author{})
|
||||
}
|
||||
66
internal/services/comment.go
Normal file
66
internal/services/comment.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"app/internal/dal"
|
||||
"app/internal/database"
|
||||
"app/internal/models"
|
||||
"app/internal/utils"
|
||||
"errors"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type CommentService struct {
|
||||
}
|
||||
type Comment = models.Comment
|
||||
|
||||
func (service *CommentService) Create(item Comment) (Comment, error) {
|
||||
utils.ReplaceEmptySlicesWithNil(&item)
|
||||
err := dal.Comment.Create(&item)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
err = utils.AppendAssociations(database.GetInstance(), &item)
|
||||
return item, err
|
||||
}
|
||||
func (service *CommentService) GetAll() ([]*Comment, error) {
|
||||
var comments []*Comment
|
||||
comments, err := dal.Comment.Preload(field.Associations).Find()
|
||||
return comments, err
|
||||
}
|
||||
func (service *CommentService) GetById(id uint) (*Comment, error) {
|
||||
item, err := dal.Comment.Preload(field.Associations).Where(dal.Comment.Id.Eq(id)).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
func (service *CommentService) Update(item Comment) (Comment, error) {
|
||||
utils.ReplaceEmptySlicesWithNil(&item)
|
||||
_, err := dal.Author.Updates(&item)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
err = utils.UpdateAssociations(database.GetInstance(), &item)
|
||||
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
|
||||
return item, err
|
||||
}
|
||||
func (service *CommentService) Delete(id uint) error {
|
||||
_, err := dal.Comment.Unscoped().Where(dal.Comment.Id.Eq(id)).Delete()
|
||||
return err
|
||||
}
|
||||
func (service *CommentService) Count() (int64, error) {
|
||||
amount, err := dal.Comment.Count()
|
||||
return amount, err
|
||||
}
|
||||
func (service *CommentService) SortedByOrder(fieldsSortOrder map[string]string) ([]*Comment, error) {
|
||||
return utils.SortByOrder(fieldsSortOrder, Comment{})
|
||||
}
|
||||
@@ -1,31 +1,16 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"app/internal/dialogs"
|
||||
"fmt"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/dialogs"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/models"
|
||||
"time"
|
||||
)
|
||||
|
||||
func InsertDefaultData() {
|
||||
insertPostTypes()
|
||||
insertAuthors()
|
||||
insertPosts()
|
||||
}
|
||||
|
||||
// Example of usage
|
||||
//func insertProductTypes() {
|
||||
// InsertDefaultEntityData(&ProductTypeService{}, []ProductType{
|
||||
// {Id: 1, Name: "Сырые пиломатериалы"},
|
||||
// {Id: 2, Name: "Сухие пиломатериалы"},
|
||||
// {Id: 3, Name: "Строганные доски"},
|
||||
// {Id: 4, Name: "Рейки"},
|
||||
// {Id: 5, Name: "Брус"},
|
||||
// {Id: 6, Name: "Пеллеты"},
|
||||
// })
|
||||
//}
|
||||
|
||||
func insertPosts() {
|
||||
InsertDefaultEntityData(&PostService{}, []models.Post{
|
||||
{Text: "В Кузбассе начали строить дома выше, чтобы их жители стали ближе к Богу."},
|
||||
})
|
||||
insertComments()
|
||||
}
|
||||
|
||||
func InsertDefaultEntityData[T any](service Service[T], entities []T) {
|
||||
@@ -36,3 +21,86 @@ func InsertDefaultEntityData[T any](service Service[T], entities []T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func insertPosts() {
|
||||
InsertDefaultEntityData(&PostService{}, []Post{
|
||||
{
|
||||
Id: 1,
|
||||
Text: "Жителям Кузбасса запретили болеть.",
|
||||
Deadline: time.Now().Unix(),
|
||||
AuthorId: 1,
|
||||
PostTypeId: 1,
|
||||
},
|
||||
{
|
||||
Id: 2,
|
||||
Deadline: time.Now().Add(time.Hour * 24 * 5).Unix(),
|
||||
Text: "⚡️⚡️⚡️Дома будут летать.",
|
||||
AuthorId: 2,
|
||||
PostTypeId: 2,
|
||||
},
|
||||
{
|
||||
Id: 3,
|
||||
Deadline: time.Now().Add(time.Hour * 24 * 6).Unix(),
|
||||
Text: "В Кузбассе начали строить дома выше, чтобы жители были ближе к богу и солнцу.",
|
||||
AuthorId: 3,
|
||||
PostTypeId: 3,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func insertAuthors() {
|
||||
InsertDefaultEntityData(&AuthorService{}, []Author{
|
||||
{
|
||||
Id: 1,
|
||||
Name: "ИА Кузбасс",
|
||||
},
|
||||
{
|
||||
Id: 2,
|
||||
Name: "ASTRA",
|
||||
},
|
||||
{
|
||||
Id: 3,
|
||||
Name: "ЧТД",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func insertComments() {
|
||||
InsertDefaultEntityData(&CommentService{}, []Comment{
|
||||
{
|
||||
Id: 1,
|
||||
Text: "Это просто замечательно!",
|
||||
AuthorId: 1,
|
||||
Posts: []Post{{Id: 1}},
|
||||
},
|
||||
{
|
||||
Id: 2,
|
||||
Text: "Я тоже думаю, что это замечательно!",
|
||||
AuthorId: 2,
|
||||
Posts: []Post{{Id: 2}},
|
||||
},
|
||||
{
|
||||
Id: 3,
|
||||
Text: "Я тоже думаю, что это замечательно!",
|
||||
AuthorId: 3,
|
||||
Posts: []Post{{Id: 3}},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func insertPostTypes() {
|
||||
InsertDefaultEntityData(&PostTypeService{}, []PostType{
|
||||
{
|
||||
Id: 1,
|
||||
Name: "Общество",
|
||||
},
|
||||
{
|
||||
Id: 2,
|
||||
Name: "Политика",
|
||||
},
|
||||
{
|
||||
Id: 3,
|
||||
Name: "Экономика",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"app/internal/addons/excel"
|
||||
"app/internal/dialogs"
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type ExcelModule struct{}
|
||||
@@ -9,47 +12,45 @@ type ExcelModule struct{}
|
||||
var ExcelService = application.NewService(&ExcelModule{})
|
||||
|
||||
func (s *ExcelModule) ImportAllEntities() error {
|
||||
// Example of usage:
|
||||
//postTypeService := PostTypeService{}
|
||||
//filepath, err := dialogs.OpenFileDialog("Импорт данных")
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//err = excel.ImportEntitiesFromSpreadsheet(filepath, excel.Importer{
|
||||
// SheetName: "Тип поста",
|
||||
// Loader: func(rowIndex int, row []string) error {
|
||||
// id, err := strconv.Atoi(row[0])
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// _, err = postTypeService.Create(PostType{
|
||||
// Id: uint(id),
|
||||
// Name: row[1],
|
||||
// })
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return nil
|
||||
// },
|
||||
//})
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
postTypeService := PostTypeService{}
|
||||
filepath, err := dialogs.OpenFileDialog("Импорт данных")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = excel.ImportEntitiesFromSpreadsheet(filepath, excel.Importer{
|
||||
SheetName: "Тип поста",
|
||||
Loader: func(rowIndex int, row []string) error {
|
||||
id, err := strconv.Atoi(row[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = postTypeService.Create(PostType{
|
||||
Id: uint(id),
|
||||
Name: row[1],
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ExcelModule) ExportAllEntities() error {
|
||||
// Example of usage:
|
||||
//postService := PostService{}
|
||||
//exporter := excel.Exporter[Post]{
|
||||
// SheetName: "Посты",
|
||||
// Entity: Post{},
|
||||
// Provider: postService.GetAll,
|
||||
//}
|
||||
//err := excel.ExportEntitiesToSpreadsheet("report.xlsx", exporter)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
postService := PostService{}
|
||||
exporter := excel.Exporter[Post]{
|
||||
SheetName: "Посты",
|
||||
Entity: Post{},
|
||||
Provider: postService.GetAll,
|
||||
}
|
||||
err := excel.ExportEntitiesToSpreadsheet("report.xlsx", exporter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"app/internal/database"
|
||||
"app/internal/models"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/database"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/models"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"app/internal/dal"
|
||||
"app/internal/database"
|
||||
"app/internal/models"
|
||||
"app/internal/utils"
|
||||
"errors"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/dal"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/database"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/models"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/utils"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type PostService struct {
|
||||
}
|
||||
type PostService struct{}
|
||||
type Post = models.Post
|
||||
|
||||
func (service *PostService) Create(item Post) (Post, error) {
|
||||
utils.ReplaceEmptySlicesWithNil(&item)
|
||||
err := dal.Post.Create(&item)
|
||||
err := dal.Post.Preload(field.Associations).Create(&item)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
@@ -39,20 +38,20 @@ func (service *PostService) GetById(id uint) (*Post, error) {
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (service *PostService) Update(item Post) (Post, error) {
|
||||
utils.ReplaceEmptySlicesWithNil(&item)
|
||||
_, err := dal.Post.Updates(&item)
|
||||
err := dal.Post.Preload(field.Associations).Save(&item)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
err = utils.UpdateAssociations(database.GetInstance(), &item)
|
||||
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
|
||||
return item, err
|
||||
}
|
||||
|
||||
func (service *PostService) Delete(id uint) error {
|
||||
_, err := dal.Post.Unscoped().Where(dal.Post.Id.Eq(id)).Delete()
|
||||
return err
|
||||
@@ -61,9 +60,7 @@ func (service *PostService) Count() (int64, error) {
|
||||
amount, err := dal.Post.Count()
|
||||
return amount, err
|
||||
}
|
||||
func (service *PostService) SortedByOrder(fieldsSortingOrder []utils.SortField) ([]*Post, error) {
|
||||
return utils.SortByOrder(fieldsSortingOrder, Post{})
|
||||
}
|
||||
func (service *PostService) SearchByAllTextFields(phrase string) ([]*Post, error) {
|
||||
return utils.FindPhraseByStringFields[Post](phrase, Post{})
|
||||
|
||||
func (service *PostService) SortedByOrder(fieldsSortOrder map[string]string) ([]*Post, error) {
|
||||
return utils.SortByOrder(fieldsSortOrder, Post{})
|
||||
}
|
||||
|
||||
65
internal/services/posttype.go
Normal file
65
internal/services/posttype.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"app/internal/dal"
|
||||
"app/internal/database"
|
||||
"app/internal/models"
|
||||
"app/internal/utils"
|
||||
"errors"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type PostTypeService struct {
|
||||
}
|
||||
type PostType = models.PostType
|
||||
|
||||
func (service *PostTypeService) Create(item PostType) (PostType, error) {
|
||||
utils.ReplaceEmptySlicesWithNil(&item)
|
||||
err := dal.PostType.Preload(field.Associations).Create(&item)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
err = utils.AppendAssociations(database.GetInstance(), &item)
|
||||
return item, err
|
||||
}
|
||||
func (service *PostTypeService) GetAll() ([]*PostType, error) {
|
||||
var posttypes []*PostType
|
||||
posttypes, err := dal.PostType.Preload(field.Associations).Find()
|
||||
return posttypes, err
|
||||
}
|
||||
func (service *PostTypeService) GetById(id uint) (*PostType, error) {
|
||||
item, err := dal.PostType.Preload(field.Associations).Where(dal.PostType.Id.Eq(id)).First()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
func (service *PostTypeService) Update(item PostType) (PostType, error) {
|
||||
utils.ReplaceEmptySlicesWithNil(&item)
|
||||
err := dal.PostType.Preload(field.Associations).Save(&item)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
err = utils.UpdateAssociations(database.GetInstance(), &item)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
return item, err
|
||||
}
|
||||
func (service *PostTypeService) Delete(id uint) error {
|
||||
_, err := dal.PostType.Unscoped().Where(dal.PostType.Id.Eq(id)).Delete()
|
||||
return err
|
||||
}
|
||||
func (service *PostTypeService) Count() (int64, error) {
|
||||
amount, err := dal.PostType.Count()
|
||||
return amount, err
|
||||
}
|
||||
|
||||
func (service *PostTypeService) SortedByOrder(fieldsSortOrder map[string]string) ([]*PostType, error) {
|
||||
return utils.SortByOrder(fieldsSortOrder, PostType{})
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
import "github.com/wailsapp/wails/v3/pkg/application"
|
||||
|
||||
var ExportedServices = []application.Service{
|
||||
application.NewService(&Post{}),
|
||||
application.NewService(&PostService{}),
|
||||
application.NewService(&AuthorService{}),
|
||||
application.NewService(&CommentService{}),
|
||||
application.NewService(&PostTypeService{}),
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/database"
|
||||
"gorm.io/gorm/clause"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func FindPhraseByStringFields[T any](phrase string, entity T) ([]*T, error) {
|
||||
db := database.GetInstance().Preload(clause.Associations)
|
||||
structType := reflect.TypeOf(entity)
|
||||
|
||||
for i := 0; i < structType.NumField(); i++ {
|
||||
field := structType.Field(i)
|
||||
|
||||
if field.Type.Kind() == reflect.Pointer {
|
||||
field.Type = field.Type.Elem()
|
||||
}
|
||||
|
||||
if field.Type.Kind() == reflect.String {
|
||||
db.Where(fmt.Sprintf("`%s` like ?", field.Name), "%"+phrase+"%")
|
||||
}
|
||||
}
|
||||
|
||||
var items []*T
|
||||
db.Find(&items)
|
||||
return items, nil
|
||||
}
|
||||
@@ -1,114 +1,70 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"app/internal/database"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/database"
|
||||
"github.com/kuzgoga/fogg"
|
||||
"golang.org/x/text/language"
|
||||
"golang.org/x/text/message"
|
||||
"gorm.io/gorm/clause"
|
||||
"reflect"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type SortField struct {
|
||||
Name string
|
||||
Order string
|
||||
}
|
||||
|
||||
func GetTableName(model any, db *gorm.DB) (string, error) {
|
||||
stmt := &gorm.Statement{DB: db}
|
||||
if err := stmt.Parse(model); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return stmt.Schema.Table, nil
|
||||
}
|
||||
|
||||
func GetColumnName(model any, fieldName string, db *gorm.DB) (string, error) {
|
||||
stmt := &gorm.Statement{DB: db}
|
||||
if err := stmt.Parse(model); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
field := stmt.Schema.LookUpField(fieldName)
|
||||
if field == nil {
|
||||
return "", fmt.Errorf("field '%s' not found", fieldName)
|
||||
}
|
||||
|
||||
return field.DBName, nil
|
||||
}
|
||||
|
||||
var p = message.NewPrinter(language.Russian)
|
||||
|
||||
func SortByOrder[T any](fieldsSortingOrder []SortField, entity T) ([]*T, error) {
|
||||
func SortByOrder[T any](fieldsSortOrder map[string]string, entity T) ([]*T, error) {
|
||||
var (
|
||||
orderQuery []string
|
||||
items []*T
|
||||
joins []string
|
||||
)
|
||||
|
||||
for _, item := range fieldsSortingOrder {
|
||||
for name, order := range fieldsSortOrder {
|
||||
structInfo := reflect.ValueOf(entity).Type()
|
||||
field, fieldExist := structInfo.FieldByName(item.Name)
|
||||
field, fieldExist := structInfo.FieldByName(name)
|
||||
|
||||
if !fieldExist {
|
||||
return nil, errors.New(p.Sprintf("Field %s not found", item.Name))
|
||||
return nil, errors.New(p.Sprintf("Field %s not found", name))
|
||||
}
|
||||
|
||||
if strings.ToUpper(item.Order) != "ASC" && strings.ToUpper(item.Order) != "DESC" {
|
||||
return nil, errors.New(p.Sprintf("Field `%s` can only be sorted by ASC or DESC", item.Name))
|
||||
if strings.ToUpper(order) != "ASC" && strings.ToUpper(order) != "DESC" {
|
||||
return nil, errors.New(p.Sprintf("Field `%s` can only be sorted by ASC or DESC", name))
|
||||
}
|
||||
|
||||
tag, err := fogg.Parse(string(field.Tag))
|
||||
if err != nil {
|
||||
return nil, errors.New(p.Sprintf("Failed to parse tag for `%s` failed: %s", item.Name, err))
|
||||
return nil, errors.New(p.Sprintf("Failed to parse tag for `%s` failed: %s", name, err))
|
||||
}
|
||||
|
||||
if !tag.HasTag("ui") {
|
||||
return nil, errors.New(p.Sprintf("Field `%s` doesn't have ui tag", item.Name))
|
||||
return nil, errors.New(p.Sprintf("Field `%s` doesn't have ui tag", name))
|
||||
}
|
||||
|
||||
if field.Type.Kind() == reflect.Slice {
|
||||
return nil, errors.New(p.Sprintf("Field `%s` is array and cannot be used for sorting", item.Name))
|
||||
return nil, errors.New(p.Sprintf("Field `%s` is array and cannot be used for sorting", name))
|
||||
}
|
||||
|
||||
fieldPath := tag.GetTag("ui").GetParamOr("field", "")
|
||||
if fieldPath == "" {
|
||||
tableName, err := GetTableName(entity, database.GetInstance())
|
||||
if err != nil {
|
||||
return nil, errors.New(p.Sprintf("Failed to get table name: %s", err))
|
||||
}
|
||||
columnName, err := GetColumnName(entity, field.Name, database.GetInstance())
|
||||
if err != nil {
|
||||
return nil, errors.New(p.Sprintf("Failed to get column name: %s", err))
|
||||
}
|
||||
orderQuery = append(orderQuery, fmt.Sprintf("`%s`.`%s` %s", tableName, columnName, item.Order))
|
||||
orderQuery = append(orderQuery, fmt.Sprintf("%s %s", name, order))
|
||||
} else {
|
||||
fieldsPathParts := strings.Split(fieldPath, ".")
|
||||
|
||||
if len(fieldsPathParts) > 1 {
|
||||
return nil, errors.New(p.Sprintf("Too complex fieldPath for structure `%s`", item.Name))
|
||||
return nil, errors.New(p.Sprintf("Too complex fieldPath for structure `%s`", name))
|
||||
}
|
||||
|
||||
if len(fieldsPathParts) == 0 {
|
||||
return nil, errors.New(p.Sprintf("Invalid field path for `%s` field", item.Name))
|
||||
return nil, errors.New(p.Sprintf("Invalid field path for `%s` field", name))
|
||||
}
|
||||
|
||||
joinPathParts := append([]string{field.Type.Name()}, fieldsPathParts...)
|
||||
for i, part := range joinPathParts {
|
||||
joinPathParts[i] = "`" + part + "`"
|
||||
}
|
||||
|
||||
joinField := strings.Join(joinPathParts, ".")
|
||||
joinTable := field.Type.Name()
|
||||
if !slices.Contains(joins, joinTable) {
|
||||
joins = append(joins, joinTable)
|
||||
}
|
||||
orderQuery = append(orderQuery, fmt.Sprintf("%s %s", joinField, item.Order))
|
||||
orderQuery = append(orderQuery, fmt.Sprintf("%s %s", joinField, order))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
main.go
2
main.go
@@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"app/internal/services"
|
||||
"embed"
|
||||
"git.gogacoder.ru/NTO/boilerplate/internal/services"
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"log"
|
||||
)
|
||||
|
||||
18
package-lock.json
generated
Normal file
18
package-lock.json
generated
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "boilerplate",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@wailsio/runtime": "3.0.0-alpha.66"
|
||||
}
|
||||
},
|
||||
"node_modules/@wailsio/runtime": {
|
||||
"version": "3.0.0-alpha.66",
|
||||
"resolved": "https://registry.npmjs.org/@wailsio/runtime/-/runtime-3.0.0-alpha.66.tgz",
|
||||
"integrity": "sha512-ENLu8rn1griL1gFHJqkq1i+BVxrrA0JPJHYneUJYuf/s54kjuQViW0RKDEe/WTDo56ABpfykrd/T8OYpPUyXUw==",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
package.json
Normal file
5
package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@wailsio/runtime": "3.0.0-alpha.66"
|
||||
}
|
||||
}
|
||||
22
pnpm-lock.yaml
generated
Normal file
22
pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@wailsio/runtime':
|
||||
specifier: 3.0.0-alpha.66
|
||||
version: 3.0.0-alpha.66
|
||||
|
||||
packages:
|
||||
|
||||
'@wailsio/runtime@3.0.0-alpha.66':
|
||||
resolution: {integrity: sha512-ENLu8rn1griL1gFHJqkq1i+BVxrrA0JPJHYneUJYuf/s54kjuQViW0RKDEe/WTDo56ABpfykrd/T8OYpPUyXUw==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@wailsio/runtime@3.0.0-alpha.66': {}
|
||||
Reference in New Issue
Block a user