import { AliasNode } from './alias-node.js' ; import { ColumnNode } from './column-node.js' ; import { IdentifierNode } from './identifier-node.js' ; import { OperationNode , OperationNodeKind } from './operation-node.js' ; import { ReferenceNode } from './reference-node.js' ; import { SelectAllNode } from './select-all-node.js' ; import { SelectionNode } from './selection-node.js' ; import { TableNode } from './table-node.js' ; import { AndNode } from './and-node.js' ; import { JoinNode } from './join-node.js' ; import { OrNode } from './or-node.js' ; import { ParensNode } from './parens-node.js' ; import { PrimitiveValueListNode } from './primitive-value-list-node.js' ; import { RawNode } from './raw-node.js' ; import { SelectQueryNode } from './select-query-node.js' ; import { ValueListNode } from './value-list-node.js' ; import { ValueNode } from './value-node.js' ; import { FilterNode } from './filter-node.js' ; import { OperatorNode } from './operator-node.js' ; import { FromNode } from './from-node.js' ; import { WhereNode } from './where-node.js' ; import { InsertQueryNode } from './insert-query-node.js' ; import { DeleteQueryNode } from './delete-query-node.js' ; import { ReturningNode } from './returning-node.js' ; import { CreateTableNode } from './create-table-node.js' ; import { AddColumnNode } from './add-column-node.js' ; import { DropTableNode } from './drop-table-node.js' ; import { DataTypeNode } from './data-type-node.js' ; import { OrderByNode } from './order-by-node.js' ; import { OrderByItemNode } from './order-by-item-node.js' ; import { GroupByNode } from './group-by-node.js' ; import { GroupByItemNode } from './group-by-item-node.js' ; import { UpdateQueryNode } from './update-query-node.js' ; import { ColumnUpdateNode } from './column-update-node.js' ; import { LimitNode } from './limit-node.js' ; import { OffsetNode } from './offset-node.js' ; import { OnConflictNode } from './on-conflict-node.js' ; import { CreateIndexNode } from './create-index-node.js' ; import { ListNode } from './list-node.js' ; import { DropIndexNode } from './drop-index-node.js' ; import { PrimaryKeyConstraintNode } from './primary-constraint-node.js' ; import { UniqueConstraintNode } from './unique-constraint-node.js' ; import { ReferencesNode } from './references-node.js' ; import { CheckConstraintNode } from './check-constraint-node.js' ; import { WithNode } from './with-node.js' ; import { CommonTableExpressionNode } from './common-table-expression-node.js' ; import { CommonTableExpressionNameNode } from './common-table-expression-name-node.js' ; import { HavingNode } from './having-node.js' ; import { freeze } from '../util/object-utils.js' ; import { CreateSchemaNode } from './create-schema-node.js' ; import { DropSchemaNode } from './drop-schema-node.js' ; import { AlterTableNode } from './alter-table-node.js' ; import { DropColumnNode } from './drop-column-node.js' ; import { RenameColumnNode } from './rename-column-node.js' ; import { AlterColumnNode } from './alter-column-node.js' ; import { AddConstraintNode } from './add-constraint-node.js' ; import { DropConstraintNode } from './drop-constraint-node.js' ; import { ForeignKeyConstraintNode } from './foreign-key-constraint-node.js' ; import { ColumnDefinitionNode } from './column-definition-node.js' ; import { ModifyColumnNode } from './modify-column-node.js' ; import { OnDuplicateKeyNode } from './on-duplicate-key-node.js' ; import { UnionNode } from './union-node.js' ; import { CreateViewNode } from './create-view-node.js' ; import { DropViewNode } from './drop-view-node.js' ; import { GeneratedNode } from './generated-node.js' ; import { DefaultValueNode } from './default-value-node.js' ; import { OnNode } from './on-node.js' ; import { ValuesNode } from './values-node.js' ; /**
 * Transforms an operation node tree into another one.
 *
 * Kysely queries are expressed internally as a tree of objects (operation nodes).
 * `OperationNodeTransformer` takes such a tree as its input and returns a
 * transformed deep copy of it. By default the `OperationNodeTransformer`
 * does nothing. You need to override one or more methods to make it do
 * something.
 *
 * There's a method for each node type. For example if you'd like to convert
 * each identifier (table name, column name, alias etc.) from camelCase to
 * snake_case, you'd do something like this:
 *
 * ```ts
 * class CamelCaseTransformer extends OperationNodeTransformer {
 *   transformIdentifier(node: IdentifierNode): IdentifierNode {
 *     node = super.transformIdentifier(node),
 *
 *     return {
 *       ...node,
 *       identifier: snakeCase(node.identifier),
 *     }
 *   }
 * }
 *
 * const transformer = new CamelCaseTransformer()
 * const tree = transformer.transformNode(tree)
 * ```
 */ export class OperationNodeTransformer { protected readonly nodeStack : OperationNode [ ] = [ ] ; readonly #transformers : Record < OperationNodeKind , Function > = freeze ( { AliasNode : this . transformAlias . bind ( this ) , ColumnNode : this . transformColumn . bind ( this ) , IdentifierNode : this . transformIdentifier . bind ( this ) , RawNode : this . transformRaw . bind ( this ) , ReferenceNode : this . transformReference . bind ( this ) , SelectQueryNode : this . transformSelectQuery . bind ( this ) , SelectionNode : this . transformSelection . bind ( this ) , TableNode : this . transformTable . bind ( this ) , FromNode : this . transformFrom . bind ( this ) , SelectAllNode : this . transformSelectAll . bind ( this ) , FilterNode : this . transformFilter . bind ( this ) , AndNode : this . transformAnd . bind ( this ) , OrNode : this . transformOr . bind ( this ) , ValueNode : this . transformValue . bind ( this ) , ValueListNode : this . transformValueList . bind ( this ) , PrimitiveValueListNode : this . transformPrimitiveValueList . bind ( this ) , ParensNode : this . transformParens . bind ( this ) , JoinNode : this . transformJoin . bind ( this ) , OperatorNode : this . transformOperator . bind ( this ) , WhereNode : this . transformWhere . bind ( this ) , InsertQueryNode : this . transformInsertQuery . bind ( this ) , DeleteQueryNode : this . transformDeleteQuery . bind ( this ) , ReturningNode : this . transformReturning . bind ( this ) , CreateTableNode : this . transformCreateTable . bind ( this ) , AddColumnNode : this . transformAddColumn . bind ( this ) , ColumnDefinitionNode : this . transformColumnDefinition . bind ( this ) , DropTableNode : this . transformDropTable . bind ( this ) , DataTypeNode : this . transformDataType . bind ( this ) , OrderByNode : this . transformOrderBy . bind ( this ) , OrderByItemNode : this . transformOrderByItem . bind ( this ) , GroupByNode : this . transformGroupBy . bind ( this ) , GroupByItemNode : this . transformGroupByItem . bind ( this ) , UpdateQueryNode : this . transformUpdateQuery . bind ( this ) , ColumnUpdateNode : this . transformColumnUpdate . bind ( this ) , LimitNode : this . transformLimit . bind ( this ) , OffsetNode : this . transformOffset . bind ( this ) , OnConflictNode : this . transformOnConflict . bind ( this ) , OnDuplicateKeyNode : this . transformOnDuplicateKey . bind ( this ) , CreateIndexNode : this . transformCreateIndex . bind ( this ) , DropIndexNode : this . transformDropIndex . bind ( this ) , ListNode : this . transformList . bind ( this ) , PrimaryKeyConstraintNode : this . transformPrimaryKeyConstraint . bind ( this ) , UniqueConstraintNode : this . transformUniqueConstraint . bind ( this ) , ReferencesNode : this . transformReferences . bind ( this ) , CheckConstraintNode : this . transformCheckConstraint . bind ( this ) , WithNode : this . transformWith . bind ( this ) , CommonTableExpressionNode : this . transformCommonTableExpression . bind ( this ) , CommonTableExpressionNameNode : this . transformCommonTableExpressionName . bind ( this ) , HavingNode : this . transformHaving . bind ( this ) , CreateSchemaNode : this . transformCreateSchema . bind ( this ) , DropSchemaNode : this . transformDropSchema . bind ( this ) , AlterTableNode : this . transformAlterTable . bind ( this ) , DropColumnNode : this . transformDropColumn . bind ( this ) , RenameColumnNode : this . transformRenameColumn . bind ( this ) , AlterColumnNode : this . transformAlterColumn . bind ( this ) , ModifyColumnNode : this . transformModifyColumn . bind ( this ) , AddConstraintNode : this . transformAddConstraint . bind ( this ) , DropConstraintNode : this . transformDropConstraint . bind ( this ) , ForeignKeyConstraintNode : this . transformForeignKeyConstraint . bind ( this ) , UnionNode : this . transformUnion . bind ( this ) , CreateViewNode : this . transformCreateView . bind ( this ) , DropViewNode : this . transformDropView . bind ( this ) , GeneratedNode : this . transformGenerated . bind ( this ) , DefaultValueNode : this . transformDefaultValue . bind ( this ) , OnNode : this . transformOn . bind ( this ) , ValuesNode : this . transformValues . bind ( this ) , } ) ; readonly transformNode = < T extends OperationNode | undefined > ( node ) : T => { if ( ! node ) { return undefined as unknown as any ; } this . nodeStack . push ( node ) ; const out = this . #transformers [ node . kind ] ( node ) ; this . nodeStack . pop ( ) ; return freeze ( out ) ; } ; protected transformNodeList < T extends OperationNode > ( list ) { if ( ! list ) { return list as unknown as T [ ] ; } return freeze ( list . map ( this . transformNode ) as T [ ] ) ; } protected transformSelectQuery ( node ) { return { kind : 'SelectQueryNode' , from : this . transformNode ( node . from ) , selections : this . transformNodeList ( node . selections ) , distinctOnSelections : this . transformNodeList ( node . distinctOnSelections ) , distinct : node . distinct , joins : this . transformNodeList ( node . joins ) , groupBy : this . transformNode ( node . groupBy ) , orderBy : this . transformNode ( node . orderBy ) , where : this . transformNode ( node . where ) , modifiers : node . modifiers , limit : this . transformNode ( node . limit ) , offset : this . transformNode ( node . offset ) , with : this . transformNode ( node . with ) , having : this . transformNode ( node . having ) , union : this . transformNodeList ( node . union ) , } ; } protected transformSelection ( node ) { return { kind : 'SelectionNode' , selection : this . transformNode ( node . selection ) , } ; } protected transformColumn ( node ) { return { kind : 'ColumnNode' , column : this . transformNode ( node . column ) , } ; } protected transformAlias ( node ) { return { kind : 'AliasNode' , node : this . transformNode ( node . node ) , alias : this . transformNode ( node . alias ) , } ; } protected transformTable ( node ) { return { kind : 'TableNode' , schema : this . transformNode ( node . schema ) , table : this . transformNode ( node . table ) , } ; } protected transformFrom ( node ) { return { kind : 'FromNode' , froms : this . transformNodeList ( node . froms ) , } ; } protected transformReference ( node ) { return { kind : 'ReferenceNode' , table : this . transformNode ( node . table ) , column : this . transformNode ( node . column ) , } ; } protected transformFilter ( node ) { return { kind : 'FilterNode' , left : this . transformNode ( node . left ) , op : this . transformNode ( node . op ) , right : this . transformNode ( node . right ) , } ; } protected transformAnd ( node ) { return { kind : 'AndNode' , left : this . transformNode ( node . left ) , right : this . transformNode ( node . right ) , } ; } protected transformOr ( node ) { return { kind : 'OrNode' , left : this . transformNode ( node . left ) , right : this . transformNode ( node . right ) , } ; } protected transformValueList ( node ) { return { kind : 'ValueListNode' , values : this . transformNodeList ( node . values ) , } ; } protected transformParens ( node ) { return { kind : 'ParensNode' , node : this . transformNode ( node . node ) , } ; } protected transformJoin ( node ) { return { kind : 'JoinNode' , joinType : node . joinType , table : this . transformNode ( node . table ) , on : this . transformNode ( node . on ) , } ; } protected transformRaw ( node ) { return { kind : 'RawNode' , sqlFragments : freeze ( [ ... node . sqlFragments ] ) , params : this . transformNodeList ( node . params ) , } ; } protected transformWhere ( node ) { return { kind : 'WhereNode' , where : this . transformNode ( node . where ) , } ; } protected transformInsertQuery ( node ) { return { kind : 'InsertQueryNode' , into : this . transformNode ( node . into ) , columns : this . transformNodeList ( node . columns ) , values : this . transformNode ( node . values ) , returning : this . transformNode ( node . returning ) , onConflict : this . transformNode ( node . onConflict ) , onDuplicateKey : this . transformNode ( node . onDuplicateKey ) , with : this . transformNode ( node . with ) , ignore : node . ignore , } ; } protected transformValues ( node ) { return { kind : 'ValuesNode' , values : this . transformNodeList ( node . values ) , } ; } protected transformDeleteQuery ( node ) { return { kind : 'DeleteQueryNode' , from : this . transformNode ( node . from ) , joins : this . transformNodeList ( node . joins ) , where : this . transformNode ( node . where ) , returning : this . transformNode ( node . returning ) , with : this . transformNode ( node . with ) , } ; } protected transformReturning ( node ) { return { kind : 'ReturningNode' , selections : this . transformNodeList ( node . selections ) , } ; } protected transformCreateTable ( node ) { return { kind : 'CreateTableNode' , table : this . transformNode ( node . table ) , columns : this . transformNodeList ( node . columns ) , constraints : this . transformNodeList ( node . constraints ) , temporary : node . temporary , ifNotExists : node . ifNotExists , onCommit : node . onCommit , } ; } protected transformColumnDefinition ( node ) { return { kind : 'ColumnDefinitionNode' , column : this . transformNode ( node . column ) , dataType : this . transformNode ( node . dataType ) , references : this . transformNode ( node . references ) , primaryKey : node . primaryKey , autoIncrement : node . autoIncrement , unique : node . unique , notNull : node . notNull , unsigned : node . unsigned , defaultTo : this . transformNode ( node . defaultTo ) , check : this . transformNode ( node . check ) , generated : this . transformNode ( node . generated ) , } ; } protected transformAddColumn ( node ) { return { kind : 'AddColumnNode' , column : this . transformNode ( node . column ) , } ; } protected transformDropTable ( node ) { return { kind : 'DropTableNode' , table : this . transformNode ( node . table ) , ifExists : node . ifExists , } ; } protected transformOrderBy ( node ) { return { kind : 'OrderByNode' , items : this . transformNodeList ( node . items ) , } ; } protected transformOrderByItem ( node ) { return { kind : 'OrderByItemNode' , orderBy : this . transformNode ( node . orderBy ) , direction : this . transformNode ( node . direction ) , } ; } protected transformGroupBy ( node ) { return { kind : 'GroupByNode' , items : this . transformNodeList ( node . items ) , } ; } protected transformGroupByItem ( node ) { return { kind : 'GroupByItemNode' , groupBy : this . transformNode ( node . groupBy ) , } ; } protected transformUpdateQuery ( node ) { return { kind : 'UpdateQueryNode' , table : this . transformNode ( node . table ) , joins : this . transformNodeList ( node . joins ) , where : this . transformNode ( node . where ) , updates : this . transformNodeList ( node . updates ) , returning : this . transformNode ( node . returning ) , with : this . transformNode ( node . with ) , } ; } protected transformColumnUpdate ( node ) { return { kind : 'ColumnUpdateNode' , column : this . transformNode ( node . column ) , value : this . transformNode ( node . value ) , } ; } protected transformLimit ( node ) { return { kind : 'LimitNode' , limit : this . transformNode ( node . limit ) , } ; } protected transformOffset ( node ) { return { kind : 'OffsetNode' , offset : this . transformNode ( node . offset ) , } ; } protected transformOnConflict ( node ) { return { kind : 'OnConflictNode' , columns : this . transformNodeList ( node . columns ) , constraint : this . transformNode ( node . constraint ) , indexExpression : this . transformNode ( node . indexExpression ) , indexWhere : this . transformNode ( node . indexWhere ) , updates : this . transformNodeList ( node . updates ) , updateWhere : this . transformNode ( node . updateWhere ) , doNothing : node . doNothing , } ; } protected transformOnDuplicateKey ( node ) { return { kind : 'OnDuplicateKeyNode' , updates : this . transformNodeList ( node . updates ) , } ; } protected transformCreateIndex ( node ) { return { kind : 'CreateIndexNode' , name : this . transformNode ( node . name ) , table : this . transformNode ( node . table ) , expression : this . transformNode ( node . expression ) , unique : node . unique , using : this . transformNode ( node . using ) , } ; } protected transformList ( node ) { return { kind : 'ListNode' , items : this . transformNodeList ( node . items ) , } ; } protected transformDropIndex ( node ) { return { kind : 'DropIndexNode' , name : this . transformNode ( node . name ) , table : this . transformNode ( node . table ) , ifExists : node . ifExists , } ; } protected transformPrimaryKeyConstraint ( node ) { return { kind : 'PrimaryKeyConstraintNode' , columns : this . transformNodeList ( node . columns ) , name : this . transformNode ( node . name ) , } ; } protected transformUniqueConstraint ( node ) { return { kind : 'UniqueConstraintNode' , columns : this . transformNodeList ( node . columns ) , name : this . transformNode ( node . name ) , } ; } protected transformForeignKeyConstraint ( node ) { return { kind : 'ForeignKeyConstraintNode' , columns : this . transformNodeList ( node . columns ) , references : this . transformNode ( node . references ) , name : this . transformNode ( node . name ) , onDelete : node . onDelete , onUpdate : node . onUpdate , } ; } protected transformUnion ( node ) { return { kind : 'UnionNode' , union : this . transformNode ( node . union ) , all : node . all , } ; } protected transformReferences ( node ) { return { kind : 'ReferencesNode' , table : this . transformNode ( node . table ) , columns : this . transformNodeList ( node . columns ) , onDelete : node . onDelete , onUpdate : node . onUpdate , } ; } protected transformCheckConstraint ( node ) { return { kind : 'CheckConstraintNode' , expression : this . transformNode ( node . expression ) , name : this . transformNode ( node . name ) , } ; } protected transformWith ( node ) { return { kind : 'WithNode' , expressions : this . transformNodeList ( node . expressions ) , recursive : node . recursive , } ; } protected transformCommonTableExpression ( node ) { return { kind : 'CommonTableExpressionNode' , name : this . transformNode ( node . name ) , expression : this . transformNode ( node . expression ) , } ; } protected transformCommonTableExpressionName ( node ) { return { kind : 'CommonTableExpressionNameNode' , table : this . transformNode ( node . table ) , columns : this . transformNodeList ( node . columns ) , } ; } protected transformHaving ( node ) { return { kind : 'HavingNode' , having : this . transformNode ( node . having ) , } ; } protected transformCreateSchema ( node ) { return { kind : 'CreateSchemaNode' , schema : this . transformNode ( node . schema ) , } ; } protected transformDropSchema ( node ) { return { kind : 'DropSchemaNode' , schema : this . transformNode ( node . schema ) , ifExists : node . ifExists , } ; } protected transformAlterTable ( node ) { return { kind : 'AlterTableNode' , table : this . transformNode ( node . table ) , renameTo : this . transformNode ( node . renameTo ) , setSchema : this . transformNode ( node . setSchema ) , renameColumn : this . transformNode ( node . renameColumn ) , addColumn : this . transformNode ( node . addColumn ) , dropColumn : this . transformNode ( node . dropColumn ) , alterColumn : this . transformNode ( node . alterColumn ) , modifyColumn : this . transformNode ( node . modifyColumn ) , addConstraint : this . transformNode ( node . addConstraint ) , dropConstraint : this . transformNode ( node . dropConstraint ) , } ; } protected transformDropColumn ( node ) { return { kind : 'DropColumnNode' , column : this . transformNode ( node . column ) , } ; } protected transformRenameColumn ( node ) { return { kind : 'RenameColumnNode' , column : this . transformNode ( node . column ) , renameTo : this . transformNode ( node . renameTo ) , } ; } protected transformAlterColumn ( node ) { return { kind : 'AlterColumnNode' , column : this . transformNode ( node . column ) , dataType : this . transformNode ( node . dataType ) , dataTypeExpression : this . transformNode ( node . dataTypeExpression ) , setDefault : this . transformNode ( node . setDefault ) , dropDefault : node . dropDefault , setNotNull : node . setNotNull , dropNotNull : node . dropNotNull , } ; } protected transformModifyColumn ( node ) { return { kind : 'ModifyColumnNode' , column : this . transformNode ( node . column ) , } ; } protected transformAddConstraint ( node ) { return { kind : 'AddConstraintNode' , constraint : this . transformNode ( node . constraint ) , } ; } protected transformDropConstraint ( node ) { return { kind : 'DropConstraintNode' , constraintName : this . transformNode ( node . constraintName ) , } ; } protected transformCreateView ( node ) { return { kind : 'CreateViewNode' , name : this . transformNode ( node . name ) , temporary : node . temporary , orReplace : node . orReplace , ifNotExists : node . ifNotExists , materialized : node . materialized , columns : this . transformNodeList ( node . columns ) , as : this . transformNode ( node . as ) , } ; } protected transformDropView ( node ) { return { kind : 'DropViewNode' , name : this . transformNode ( node . name ) , ifExists : node . ifExists , materialized : node . materialized , } ; } protected transformGenerated ( node ) { return { kind : 'GeneratedNode' , byDefault : node . byDefault , always : node . always , identity : node . identity , stored : node . stored , expression : this . transformNode ( node . expression ) , } ; } protected transformDefaultValue ( node ) { return { kind : 'DefaultValueNode' , defaultValue : this . transformNode ( node . defaultValue ) , } ; } protected transformOn ( node ) { return { kind : 'OnNode' , on : this . transformNode ( node . on ) , } ; } protected transformDataType ( node ) { return node ; } protected transformSelectAll ( node ) { return node ; } protected transformIdentifier ( node ) { return node ; } protected transformValue ( node ) { return node ; } protected transformPrimitiveValueList ( node ) { return node ; } protected transformOperator ( node ) { return node ; } }