{{#trim-trailing-whitespace}}
/**
 * DO NOT EDIT:
 *
 * This file has been auto-generated from database schema using ts-sql-codegen.
 * Any changes will be overwritten.
 */
import { {{table.kind}} } from "ts-sql-query/{{table.kind}}{{output.import.extension}}";
import type { DBConnection } from "{{dbConnectionSource}}{{output.import.extension}}";
{{#if importExtraTypes}}
import {
    {{#if rowTypes.insertable}}
    InsertableRow,
    {{/if}}
    {{#if rowTypes.updatable}}
    UpdatableRow,
    {{/if}}
    {{#if rowTypes.selected}}
    SelectedRow,
    {{else if repo}}
    SelectedRow,
    {{/if}}
    {{#if valuesTypes.insertable}}
    InsertableValues,
    {{/if}}
    {{#if valuesTypes.updatable}}
    UpdatableValues,
    {{/if}}
    {{#if valuesTypes.selected}}
    SelectedValues,
    {{/if}}
} from "ts-sql-query/extras/types{{output.import.extension}}";
{{/if}}
{{#each imports}}
    {{#if isDefault}}
        {{#each imported}}
            {{#dedent-by 4 "level"}}
                import {{.}} from "{{../importPath}}{{../../output.import.extension}}";
            {{/dedent-by}}
        {{/each}}
    {{else}}
        {{#dedent-by 3 "level"}}
            import {
                {{#dedent-by 2 "level"}}
                    {{#each imported}}
                        {{.}},
                    {{/each}}
                {{/dedent-by}}
            } from "{{importPath}}{{../output.import.extension}}";
        {{/dedent-by}}
    {{/if}}
{{/each}}

{{#each table.comment}}
{{this}}
{{/each}}
{{#if exportTableClass}}export {{/if}}class {{className}} extends {{table.kind}}<DBConnection, '{{table.idPrefix}}{{className}}'> {
    {{#dedent-by 3 "level"}}
        {{#each fields}}
            {{#each this.comment}}
                {{this}}
            {{/each}}
            {{#if fieldType.kind}}
                {{#if includeDBTypeWhenIsOptional}}
                {{name}} = this.{{columnMethod}}<{{fieldType.tsType.name}}, '{{fieldType.dbType.name}}'>('{{columnName}}', '{{fieldType.kind}}', '{{fieldType.dbType.name}}'{{#if fieldType.adapter}}, {{fieldType.adapter.name}}{{/if}});
                {{else}}
                {{name}} = this.{{columnMethod}}<{{fieldType.tsType.name}}>('{{columnName}}', '{{fieldType.kind}}', '{{fieldType.dbType.name}}'{{#if fieldType.adapter}}, {{fieldType.adapter.name}}{{/if}});
                {{/if}}
            {{else}}
                {{name}} = this.{{columnMethod}}('{{columnName}}', '{{fieldType.dbType.name}}'{{#if fieldType.adapter}}, {{fieldType.adapter.name}}{{/if}});
            {{/if}}
        {{/each}}
    {{/dedent-by}}

    constructor() {
        super('{{table.name}}');
    }
}
{{#if colMapping}}

export type {{colMapping.name}} = {
    {{#each fields}}
    {{#if fieldType.kind}}
    {{name}}: ['{{fieldType.kind}}', {{fieldType.tsType.name}}]
    {{else}}
    {{name}}: '{{fieldType.dbType.name}}'
    {{/if}}
    {{/each}}
}
{{/if}}

{{#if instName}}
export const {{instName}} = new {{className}}();
{{/if}}

{{#each rowTypes}}
{{#if isInterface}}
export interface {{name}} extends {{{expr}}} {}
{{else}}
export type {{name}} = {{{expr}}};
{{/if}}
{{/each}}
{{#each valuesTypes}}
{{#if isInterface}}
export interface {{name}} extends {{{expr}}} {}
{{else}}
export type {{name}} = {{{expr}}};
{{/if}}
{{/each}}
{{#if colSetName}}
export const {{colSetName}} = extractColumnsFrom({{instName}});
{{/if}}
{{/trim-trailing-whitespace}}
{{#if repo}}
export type {{className}}Pk = SelectedRow<{{className}}>["{{pkField.name}}"];

export class {{repo.className}} {
    constructor(
        public getConnection: () => DBConnection,
        public table: {{className}}{{#if instName}} = {{instName}}{{/if}},
    ) {}

    tableCols = {{#if colSetName}}{{colSetName}}{{else}}extractColumnsFrom(this.table){{/if}};
    {{#if repo.methods.select}}

    select(conn = this.getConnection()) {
        return conn.selectFrom(this.table);
    }
    {{/if}}
    {{#if repo.methods.selectWhere}}

    selectWhere(cond: DynamicCondition<{{colMapping.name}}>, conn = this.getConnection()) {
        return this.select(conn)
            .where(conn.dynamicConditionFor(this.tableCols).withValues(cond))
            .select(this.tableCols)
            .executeSelectMany();
    }
    {{/if}}
    {{#if repo.methods.findAll}}

    {{repo.methods.findAll}}(conn = this.getConnection()) {
        return this.select(conn)
            .select(this.tableCols)
            .executeSelectMany();
    }
    {{/if}}
    {{#if repo.methods.findOne}}

    {{repo.methods.findOne}}({{pkField.name}}: {{className}}Pk, conn = this.getConnection()) {
        return this.select(conn)
            .where(this.table.{{pkField.name}}.equals({{pkField.name}}))
            .select(this.tableCols)
            .executeSelectNoneOrOne();
    }
    {{/if}}
    {{#if repo.methods.findMany}}

    {{repo.methods.findMany}}({{pkField.name}}List: {{className}}Pk[], conn = this.getConnection()) {
        return this.select(conn)
            .where(this.table.{{pkField.name}}.in({{pkField.name}}List))
            .select(this.tableCols)
            .executeSelectMany();
    }
    {{/if}}
    {{#if repo.methods.insert}}

    insert(conn = this.getConnection()) {
        return conn.insertInto(this.table);
    }
    {{/if}}
    {{#if repo.methods.insertOne}}

    {{repo.methods.insertOne}}(row: {{rowTypes.insertable.name}}, conn = this.getConnection()) {
        return this.insert(conn)
            .set(row)
            .returning(this.tableCols)
            .executeInsertOne();
    }
    {{/if}}
    {{#if repo.methods.insertMany}}

    {{repo.methods.insertMany}}(rows: {{rowTypes.insertable.name}}[], conn = this.getConnection()) {
        return this.insert(conn)
            .values(rows)
            .returning(this.tableCols)
            .executeInsertMany();
    }
    {{/if}}
    {{#if repo.methods.update}}

    update(conn = this.getConnection()) {
        return conn.update(this.table);
    }
    {{/if}}
    {{#if repo.methods.updateOne}}

    {{repo.methods.updateOne}}({{pkField.name}}: {{className}}Pk, update: {{rowTypes.updatable.name}}, conn = this.getConnection()) {
        return this.update(conn)
            .set(update)
            .where(this.table.{{pkField.name}}.equals({{pkField.name}}))
            .returning(this.tableCols)
            .executeUpdateOne();
    }
    {{/if}}
    {{#if repo.methods.updateMany}}

    {{repo.methods.updateMany}}({{pkField.name}}List: {{className}}Pk[], update: {{rowTypes.updatable.name}}, conn = this.getConnection()) {
        return this.update(conn)
            .set(update)
            .where(this.table.{{pkField.name}}.in({{pkField.name}}List))
            .returning(this.tableCols)
            .executeUpdateMany();
    }
    {{/if}}
    {{#if repo.methods.delete}}

    delete(conn = this.getConnection()) {
        return conn.deleteFrom(this.table);
    }
    {{/if}}
    {{#if repo.methods.deleteOne}}

    {{repo.methods.deleteOne}}({{pkField.name}}: {{className}}Pk, conn = this.getConnection()) {
        return this.delete(conn)
            .where(this.table.{{pkField.name}}.equals({{pkField.name}}))
            .returning(this.tableCols)
            .executeDeleteOne();
    }
    {{/if}}
    {{#if repo.methods.deleteMany}}

    {{repo.methods.deleteMany}}({{pkField.name}}List: {{className}}Pk[], conn = this.getConnection()) {
        return this.delete(conn)
            .where(this.table.{{pkField.name}}.in({{pkField.name}}List))
            .returning(this.tableCols)
            .executeDeleteMany();
    }
    {{/if}}
}
{{/if}}
